CDQ分治
递归处理左边的操作,再计算影响,然后处理右边的操作。
使用一个树状数组,利用排序x坐标的单调性,然后直接在树状数组上操作就行了。
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
struct Do{
int flag,x,y,id,v,pos;
friend bool operator <(const Do &a,const Do &b){
return a.x==b.x?(a.y==b.y?a.pos<b.pos:a.y<b.y):a.x<b.x;
}
}Q[200005],tmp[200005];
int s,w,tot,_Y[210005],toty,ans[10005],totans,BIT[200005],t1,t2,cnt;
int lowbit(int x){
return x&(-x);
}
void Add(int pos,int val){
while(pos<=toty){
BIT[pos]+=val;
pos+=lowbit(pos);
}
}
int Query(int pos){
int ans=0;
while(pos){
ans+=BIT[pos];
pos-=lowbit(pos);
}
return ans;
}
void CDQ(int l,int r){
if(l==r)return;
int mid=l+r>>1,t1=l,t2=mid+1;
for(int i=l;i<=r;i++){
//printf("Hello!:%d %d %d %d %d\n",Q[i].id,mid,Q[i].flag,Q[i].fg,Q[i].pos);
if(Q[i].id<=mid && Q[i].flag==1){Add(Q[i].y,Q[i].v);/*printf("Reggle:%d %d\n",Query(Q[i].y),Q[i].v);*/}
if(Q[i].id>mid && Q[i].flag==2){/*puts("233");printf("Leggle:%d\n",Query(Q[i].y));*/ans[Q[i].pos]+=Q[i].v*Query(Q[i].y);}
}
for(int i=l;i<=r;i++){
if(Q[i].id<=mid && Q[i].flag==1)Add(Q[i].y,-Q[i].v);
}
for(int i=l;i<=r;i++){
if(Q[i].id<=mid)tmp[t1++]=Q[i];
else tmp[t2++]=Q[i];
}
for(int i=l;i<=r;i++){
Q[i]=tmp[i];
}
CDQ(l,mid);
CDQ(mid+1,r);
}
int main(){
freopen("1176.in","r",stdin);
freopen("1176.out","w",stdout);
scanf("%d %d",&s,&w);
while(scanf("%d",&Q[++tot].flag)!=EOF){
if(Q[tot].flag==3){tot--;break;}
if(Q[tot].flag==1){
scanf("%d %d %d",&Q[tot].x,&Q[tot].y,&Q[tot].v);
_Y[++toty]=Q[tot].y;
Q[tot].id=tot;
Q[tot].pos=0;
}
else {
int x1,x2,y1,y2;
scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
ans[++cnt]=s*(x2-x1+1)*(y2-y1+1);
Q[tot].x=x1-1;
Q[tot].y=y1-1;
Q[tot].id=tot;
Q[tot].pos=cnt;
Q[tot].v=1;
_Y[++toty]=Q[tot].y;
tot++;
Q[tot].flag=2;
Q[tot].x=x2;
Q[tot].y=y1-1;
Q[tot].id=tot;
Q[tot].pos=cnt;
Q[tot].v=-1;
tot++;
Q[tot].flag=2;
Q[tot].x=x1-1;
Q[tot].y=y2;
Q[tot].id=tot;
_Y[++toty]=Q[tot].y;
Q[tot].pos=cnt;
Q[tot].v=-1;
tot++;
Q[tot].flag=2;
Q[tot].x=x2;
Q[tot].y=y2;
Q[tot].pos=cnt;
Q[tot].id=tot;
Q[tot].v=1;
}
}
sort(_Y+1,_Y+toty+1);
toty=unique(_Y+1,_Y+toty+1)-_Y-1;
for(int i=1;i<=tot;i++){
Q[i].y=lower_bound(_Y+1,_Y+toty+1,Q[i].y)-_Y;
}
sort(Q+1,Q+tot+1);
CDQ(1,tot);
for(int i=1;i<=cnt;i++){
printf("%d\n",ans[i]);
}
return 0;
}
评论 (0)