1
7
2016
0

[BZOJ1176] [Balkan2007] Mokia

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;
}
Category: BZOJ | Tags: OI bzoj | Read Count: 623

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com