Title:
There is a chessboard with an initial color of all white n*n. each time you select a rectangular area to reverse the color, ask how many black squares there will be at the end. N, k<=10000
Analysis:
It's the same as scanning line. Record each transverse edge and project it to the x-axis. It's just that there's no distinction between the top and the bottom. After sorting by height, for each edge, project to the x-axis, and perform xor 1 operation on the projection interval once. Therefore, the segment tree maintains interval exclusive or operation, and then queries interval sum every time.
Code:
#include<bits/stdc++.h> #define lson rt<<1,l,(l+r)/2 #define rson rt<<1|1,(l+r)/2+1,r using namespace std; const int MAXN = 1e4+5; int n,k,cnt; struct Edge { int l,r,h; bool operator < (const Edge &e) const { return h < e.h; } }e[MAXN<<1]; struct Seg_Tree{ int sum[MAXN << 2], tag[MAXN<<2]; void build() { memset(sum,0,sizeof sum); memset(tag,0,sizeof tag); } void pushup(int rt) { sum[rt] = sum[rt<<1] + sum[rt<<1|1]; } void pushdown(int rt,int l,int r) { if(tag[rt]){ tag[rt<<1] ^= tag[rt]; tag[rt<<1|1] ^= tag[rt]; sum[rt<<1] = (l+r)/2 - l + 1 - sum[rt<<1]; sum[rt<<1|1] = r - (l+r)/2 - sum[rt<<1|1]; tag[rt] = 0; } } void update(int L,int R,int rt,int l,int r) { if(L<=l && R>=r){ tag[rt] ^= 1; sum[rt] = (r-l+1) - sum[rt]; return; } pushdown(rt,l,r); if(L<=(l+r)/2) update(L,R,lson); if(R>(l+r)/2) update(L,R,rson); pushup(rt); } }t; int main() { ios::sync_with_stdio(false); int T; cin >> T; while(T--) { cin >> n >> k; cnt = 0; for(int i=0;i<k;i++){ int xlow,xhigh,ylow,yhigh; cin >> xlow >> xhigh >> ylow >> yhigh; e[++cnt] = {xlow,xhigh,ylow}; e[++cnt] = {xlow,xhigh,yhigh+1}; } sort(e+1,e+cnt+1); int ans = 0; t.build(); for(int i=1;i<cnt;i++) { t.update(e[i].l,e[i].r,1,1,1e4+2); ans += t.sum[1]*(e[i+1].h-e[i].h); } cout << ans << endl; } return 0; }