传送门: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;
}