描述
题解
很巧妙的利用两个堆来搞事情,一个大顶堆,一个小顶堆,就是优先队列,维护每次能够拆除的方块儿,每拆除一个向周围扩展一次,并且删除拆掉的这个方块儿,这里用 map 处理。说白了,就是一个有趣的贪心问题,用到两种数据结构罢了, STL ……
代码
#include <iostream>
#include <cstdio>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;
const int MAXM = 1e5 + 10;
const ll MOD = 1e9 + 9;
int m;
bool vis[MAXM];
int x[MAXM];
int y[MAXM];
ll ans[MAXM];
map<pair<int, int>, int> mpi;
bool judge(int a, int b)
{
if (mpi[make_pair(a, b + 1)])
{
if (mpi[make_pair(a - 1, b)] == 0 && mpi[make_pair(a + 1, b)] == 0)
{
return 0;
}
}
if (mpi[make_pair(a + 1, b + 1)])
{
if (mpi[make_pair(a + 1, b)] == 0 && mpi[make_pair(a + 2, b)] == 0)
{
return 0;
}
}
if (mpi[make_pair(a - 1, b + 1)])
{
if (mpi[make_pair(a - 2, b)] == 0 && mpi[make_pair(a - 1, b)] == 0)
{
return 0;
}
}
return 1;
}
template <class T>
inline bool scan_d(T &ret)
{
char c;
int sgn;
if (c = getchar(), c == EOF)
{
return 0; //EOF
}
while (c != '-' && (c < '0' || c > '9'))
{
c = getchar();
}
sgn = (c == '-') ? -1 : 1;
ret = (c == '-') ? 0 : (c - '0');
while (c = getchar(), c >= '0' && c <= '9')
{
ret = ret * 10 + (c - '0');
}
ret *= sgn;
return 1;
}
int main()
{
scan_d(m);
for (int i = 1; i <= m; i++)
{
scan_d(x[i]), scan_d(y[i]);
mpi[make_pair(x[i], y[i])] = i;
}
priority_queue<int> mx; // 大顶堆
priority_queue<int, vector<int>, greater<int> > mn; // 小顶堆
for (int i = 1; i <= m; i++)
{
if (judge(x[i], y[i]))
{
mx.push(mpi[make_pair(x[i], y[i])]);
mn.push(mpi[make_pair(x[i], y[i])]);
}
}
int a, b;
for (int i = 1; i <= m; i++)
{
if (i & 1)
{
ans[i] = mx.top();
mx.pop();
}
else
{
ans[i] = mn.top();
mn.pop();
}
if (vis[ans[i]])
{
i--;
continue;
}
if (!judge(x[ans[i]], y[ans[i]]))
{
i--;
continue;
}
vis[ans[i]] = 1;
a = x[ans[i]];
b = y[ans[i]];
mpi.erase(make_pair(a, b));
if (mpi[make_pair(a - 1, b - 1)])
{
if (judge(a - 1, b - 1))
{
mx.push(mpi[make_pair(a - 1, b - 1)]);
mn.push(mpi[make_pair(a - 1, b - 1)]);
}
}
if (mpi[make_pair(a, b - 1)])
{
if (judge(a, b - 1))
{
mx.push(mpi[make_pair(a, b - 1)]);
mn.push(mpi[make_pair(a, b - 1)]);
}
}
if (mpi[make_pair(a + 1, b - 1)])
{
if (judge(a + 1, b - 1))
{
mx.push(mpi[make_pair(a + 1, b - 1)]);
mn.push(mpi[make_pair(a + 1, b - 1)]);
}
}
}
ll tmp = 1;
ll res = 0;
for (int i = m; i >= 1; i--)
{
res += (ans[i] - 1) * tmp;
res %= MOD;
tmp *= m;
tmp %= MOD;
}
cout << res << endl;
return 0;
}