給定平面黑點,其餘為白點。白點若上下左右均有黑點則變黑。求最終黑點總數。等價於:黑點構成的水平、垂直線段(不含端點)的交點數 + 原黑點數。
// Hash 版 BIT,避免離散化
struct HashBIT {
struct Node { int key, val; Node* nxt; };
Node* head[1001001];
int& operator[](int key) {
int pos = key % 1001001;
for (Node* p=head[pos]; p; p=p->nxt) if (p->key==key) return p->val;
return (head[pos]=new Node{key,0,head[pos]})->val;
}
void add(int x, int v) { for(;x;x-=x&-x) (*this)[x] += v; }
int query(int x) { int r=0; for(;x<=2000000007;x+=x&-x) r+=(*this)[x]; return r; }
} bit;
// 構建水平線段(同 y、相鄰黑點間)
sort(points by y, then x);
for i=2..n if (p[i].y==p[i-1].y && p[i].x >= p[i-1].x+2)
add_interval(p[i-1].x+1, p[i].x-1, p[i].y);
// 構建垂直查詢(同 x、相鄰黑點間)
sort(points by x, then y);
for i=2..n if (p[i].x==p[i-1].x && p[i].y >= p[i-1].y+2) {
add_query(p[i].x, p[i-1].y, -1);
add_query(p[i].x, p[i].y-1, +1);
}
// 掃描線處理
sort(intervals by y); sort(queries by y);
for each query:
while (interval.y <= query.y) bit.add(interval.l, -1), bit.add(interval.r, +1), interval++;
ans += bit.query(query.x) * query.flag;