[bzoj1176]Mokia

[bzoj1176]Mokia


CDQ分治。

注意树状数组不要直接 memset或暴力赋值,这里重新对每个节点add一次相反数就行了。

  • 代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
struct quest{
    int opt;
    int id,x,y,sum;
}q[N];
bool cmpx(const quest a,const quest b){
    if(a.x==b.x)
        if(a.y==b.y)return a.id<b.id;
        return a.y<b.y;
    else return a.x<b.x;
}
bool cmpy(const quest a,const quest b){
    if(a.y==b.y)return a.id<b.id;
    return a.y<b.y;
}
int n,cnt,s,w,m;
inline void ins1(int x,int y,int a,int id){
    ++cnt;q[cnt].x=x,q[cnt].y=y,q[cnt].sum=a,q[cnt].opt=1,q[cnt].id=id;
}
inline void ins2(int x1,int y1,int x2,int y2,int id){
    ++cnt;q[cnt].x=x1-1,q[cnt].y=y1-1,q[cnt].sum=1,q[cnt].opt=2,q[cnt].id=id;
    ++cnt;q[cnt].x=x2,q[cnt].y=y2,q[cnt].sum=1,q[cnt].opt=2,q[cnt].id=id;
    ++cnt;q[cnt].x=x1-1,q[cnt].y=y2,q[cnt].sum=-1,q[cnt].opt=2,q[cnt].id=id;
    ++cnt;q[cnt].x=x2,q[cnt].y=y1-1,q[cnt].sum=-1,q[cnt].opt=2,q[cnt].id=id;
}
int op[N];
int ans[N];
#define lowbit(x) ((x)&(-x))
int t[N];
inline void add(int x,int sum){
    for(;x<=m;x+=lowbit(x))t[x]+=sum;
}
inline int qry(int x){
    int ret=0;
    for(;x;x-=lowbit(x))ret+=t[x];
    return ret;
}
void cdq(int l,int r){
    if(l==r)return;
    int mid=(l+r)>>1;
    cdq(l,mid);cdq(mid+1,r);
    int j=mid+1;
    for(int i=l;i<=mid;i++){
        while(j<=r&&q[j].y<q[i].y){
            if(q[j].opt==2)
                ans[q[j].id]+=q[j].sum*qry(q[j].id);
            j++;
        }
        if(q[i].opt==1)add(q[i].id,q[i].sum);
    }
    while(j<=r){
        if(q[j].opt==2) 
            ans[q[j].id]+=q[j].sum*qry(q[j].id);
        j++;
    }
    for(int i=l;i<=mid;i++)
        if(q[i].opt==1)add(q[i].id,-1*q[i].sum);
    sort(q+l,q+r+1,cmpy);
}

int main()
{
    scanf("%d%d",&s,&w);
    m=0;
    while(true){
        int opt=0;
        scanf("%d",&opt);
        op[m+1]=opt;
        if(opt==3)break;
        if(opt==1){
            int x,y,a;
            scanf("%d%d%d",&x,&y,&a);
            ins1(x,y,a,++m);
        }
        if(opt==2){
            int x1,y1,x2,y2;
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            ins2(x1,y1,x2,y2,++m);
            ans[m]=s*(x2-x1+1)*(y2-y1+1);
        }
    }
    sort(q+1,q+cnt+1,cmpx);
    cdq(1,cnt);
    for(int i=1;i<=m;i++)if(op[i]==2){
        printf("%d\n",ans[i]);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_35923186/article/details/83048900