传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1176
我就不写分治你咬我呀
树状数组套平衡树感觉没什么好讲的
Code:
#include<cstdio> #include<cctype> #include<climits> #include<iostream> #include<algorithm> using namespace std; const int maxn=2e6+5; struct node{ int val,key,sum,s; node *c[2]; node(int _val=0,int _s=0,node *C=0){ val=_val;key=rand();sum=s=_s; c[0]=c[1]=C; } void rz(){ sum=c[0]->sum+s+c[1]->sum; } }pool[maxn],*Null; node *newnode(int _val=0,int _s=0,node *C=0){ static int tot=0; if(tot<maxn){ pool[tot].val=_val; pool[tot].key=rand(); pool[tot].sum=pool[tot].s=_s; pool[tot].c[0]=pool[tot].c[1]=C; return &pool[tot++]; }else return new node(_val,_s,C); } struct Treap{ node *root; void init(){ root=Null; } void rot(node *&t,bool d){ node *p=t->c[d];t->c[d]=p->c[!d]; p->c[!d]=t;t->rz();p->rz();t=p; } void insert(node *&t,int val,int s){ if(t==Null){t=newnode(val,s,Null);return;} if(t->val==val){t->s+=s;t->sum+=s;return;} bool d=t->val<val; insert(t->c[d],val,s); if(t->c[d]->key<t->key)rot(t,d); else t->rz(); } int Qsum(node *t,int x){ int ans=0; while(t!=Null){ if(t->val<=x)ans+=t->c[0]->sum+t->s,t=t->c[1]; else t=t->c[0]; }return ans; } void insert(int val,int s){insert(root,val,s);} int Qsum(int l,int r){return Qsum(root,r)-Qsum(root,l-1);} }; inline int lowbit(int x){return x&-x;} Treap d[maxn]; int get(int x1,int y1,int x2,int y2){ int ans=0;x1--; while(x2) ans+=d[x2].Qsum(y1,y2),x2-=lowbit(x2); while(x1) ans-=d[x1].Qsum(y1,y2),x1-=lowbit(x1); return ans; } int w,s; void updata(int x,int y,int s){ while(x<=w){ d[x].insert(y,s); x+=lowbit(x); } } int x,y,x1,y1,x2,y2,a; int main(){ Null=newnode(INT_MAX,0,0); Null->key=INT_MAX;Null->c[0]=Null->c[1]=Null; scanf("%d%d",&s,&w);int op; for(int i=1;i<=w;i++)d[i].init(); while(scanf("%d",&op)!=-1){ if(op==3)break; if(op==1){ scanf("%d%d%d",&x,&y,&a); updata(x,y,a); }else{ scanf("%d%d%d%d",&x1,&y1,&x2,&y2); printf("%d\n",s*(x2-x1+1)*(y2-y1+1)+get(x1,y1,x2,y2)); } } return 0; }