bzoj 1176: [Balkan2007]Mokia

关键在于吧询问用容斥拆成4个点

/**************************************************************
    Problem: 1176
    User: lxy8584099
    Language: C++
    Result: Accepted
    Time:5432 ms
    Memory:18796 kb
****************************************************************/
 
/*
    三维偏序 时间戳算一维
    先把x当做第一维排序 时间当做第二维 y当做第三维
    那么时间 也就是第二维就要用分治了 第三维树状数组 
    修改一个点
    查询拆成4个点 ++-- 容斥 4个点时间戳也要不一样 
*/
#include<cstdio>
#include<algorithm>
#define lowbit(x) ((x)&(-x))
#define mid ((l+r)>>1)
using namespace std;
const int N=200005;
struct pp 
{
    int x,y,id,dfn,val,opt;
    pp()
    {
        x=y=id=dfn=val=opt=0;
    }
} a[N],b[N]; 
// id表示示是第几个询问 
// val表示增加的值或者++-- opt表示是否是询问操作
bool cmp(pp a,pp b)
{
    if(a.x!=b.x) return a.x<b.x;
    return a.id<b.id;
}
int s[N*10],ans[N];
int n,tot,as,res;
void add(int x,int c) {while(x<=n) s[x]+=c,x+=lowbit(x);} 
int find(int x) {res=0;while(x) res+=s[x],x-=lowbit(x);return res;} 
void CDQ(int l,int r) 
{
    if(l>=r) return ; CDQ(l,mid),CDQ(mid+1,r);
    int i=l,j=mid+1,p=l;
    while(i<=mid&&j<=r)
    {
        if(a[i].id<a[j].id) 
        {
            if(!a[i].opt) add(a[i].y,a[i].val); b[p++]=a[i++];
        }
        else
        {
            if(a[j].opt) ans[a[j].dfn]+=find(a[j].y)*a[j].val; b[p++]=a[j++];
        } 
    }
    while(i<=mid)
    {
        if(!a[i].opt) add(a[i].y,a[i].val); b[p++]=a[i++];
    }
    while(j<=r)
    {
        if(a[j].opt) ans[a[j].dfn]+=find(a[j].y)*a[j].val; b[p++]=a[j++];
    }
    for(int i=l;i<=mid;i++) if(!a[i].opt) add(a[i].y,-a[i].val);
    for(int i=l;i<=r;i++) a[i]=b[i];
}
int main()
{
    scanf("%*d%d",&n);
    for(int op,x1,x2,y1,y2,x,y,c;;)
    {
        scanf("%d",&op);
        if(op==3) break;
        else if(op==1)
        {
            scanf("%d%d%d",&x,&y,&c);
            a[++tot].x=x,a[tot].y=y,a[tot].val=c,a[tot].id=tot;
        }
        else
        {
            as++; scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            a[++tot].x=x1-1,a[tot].y=y1-1,a[tot].id=tot;
            a[tot].dfn=as,a[tot].val=1,a[tot].opt=1;
            a[++tot].x=x1-1,a[tot].y=y2,a[tot].id=tot;
            a[tot].dfn=as,a[tot].val=-1,a[tot].opt=1;
            a[++tot].x=x2,a[tot].y=y1-1,a[tot].id=tot;
            a[tot].dfn=as,a[tot].val=-1,a[tot].opt=1;
            a[++tot].x=x2,a[tot].y=y2,a[tot].id=tot;
            a[tot].dfn=as,a[tot].val=1,a[tot].opt=1;
        }
    }
    sort(a+1,a+tot+1,cmp);
    CDQ(1,tot);
    for(int i=1;i<=as;i++) printf("%d\n",ans[i]);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/lxy8584099/p/10332561.html