很裸的一道CDQ分治吧
拆操作 询问区间的时候 拆成询问四个子区间然后加加减减
根据时间顺序来二分 然后用插排降一维 最后一维树状数组维护前缀和
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> using namespace std; char c; inline void read(int &a) { a=0;do c=getchar();while(c<'0'||c>'9'); while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar(); } struct O { int x,y,ans,No,op; int add; inline friend bool operator <(O a,O b) {return a.No<b.No||a.No==b.No&&a.op<b.op;} inline void print() { printf(" x:%d y:%d ans:%d No:%d op:%d add:%d",x,y,ans,No,op,add); puts(""); } }Line[1000001]; int BIT[5000001]; int base; inline int low_bit(int a){return a&-a;} inline void Add(int x,int delta) {for(int i=x;i<=base;i+=low_bit(i))BIT[i]+=delta;} inline int Query(int x) {int res=0;for(int i=x;i;i^=low_bit(i))res+=BIT[i];return res;} void Solve(int L,int R) { if(L^R) { int Mid=(L+R)>>1; Solve(L,Mid),Solve(Mid+1,R); int j=L; for(int i=Mid+1;i<=R;i++) if(Line[i].add==0) { while(j<=Mid&&Line[j].x<=Line[i].x) { if(Line[j].add)Add(Line[j].y,Line[j].add); j++; } Line[i].ans+=Query(Line[i].y); } j--; while(j>=L) { if(Line[j].add)Add(Line[j].y,-Line[j].add); j--; } O A[R-L+2]; int x=L,y=Mid+1,con=0; while(x<=Mid&&y<=R) if(Line[x].x<=Line[y].x)A[++con]=Line[x],x++; else A[++con]=Line[y],y++; while(x<=Mid) A[++con]=Line[x],x++; while(y<=R) A[++con]=Line[y],y++; /* for(int i=1;i<=con;i++) A[i].print(); */ for(int i=L;i<=R;i++) Line[i]=A[i-L+1]; // puts("");puts("");puts("");puts(""); } else return; } int main() { int S,W; read(S),read(W); base=W<<1; /*for(int i=1;i<=W;i++) Add(i,S); */ int n=0,j,jk=0; while(true) { read(j); if(j==3)break; n++; if(j==1) { read(Line[n].x); read(Line[n].y); read(Line[n].add); Line[n].No=0; } else { ++jk; int x1,x2,y1,y2; read(x1),read(y1),read(x2),read(y2); Line[n]=(O){x1-1,y1-1,0,jk,1,0}; Line[n].ans+=S*(x2-x1+1)*(y2-y1+1); Line[++n]=(O){x2,y2,0,jk,2,0}; Line[++n]=(O){x1-1,y2,0,jk,3,0}; Line[++n]=(O){x2,y1-1,0,jk,4,0}; } } Solve(1,n); sort(Line+1,Line+1+n); int i=1; while(Line[i].No==0)i++; for(;i<=n;i+=4) printf("%d\n",Line[i].ans+Line[i+1].ans-Line[i+2].ans-Line[i+3].ans); return 0; }