zoukankan      html  css  js  c++  java
  • AcWing267 莫基亚(CDQ分治)

    CDQ分治不但能解决三维偏序问题,还能将某些问题的动态版本变成静态。

    比如这题是单点修改,区间查询,这样我们就可以将输入的顺序当作时间轴,之后进行CDQ分治

    按x轴排序后,对y进行树状数组加减,这道题就变成了x比他小,并且y也比他小的个数查询

    这题还用到了简单的容斥原理,也就是二维前缀和的思想来求取矩形真正的内容

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const int N=2e6+10;
    const int mod=1e9+7;
    struct node{
        int a,x,y,v,op,id;
    }q[N];
    ll tr[N],ans[N];
    int lowbit(int x){
        return x&-x;
    }
    void add(int x,int c){
        int i;
        for(i=x;i<=N;i+=lowbit(i)){
            tr[i]+=c;
        }
    }
    ll sum(int x){
        ll res=0;
        int i;
        for(i=x;i;i-=lowbit(i)){
            res+=tr[i];
        }
        return res;
    }
    bool cmpb(node a,node b){
        if(a.x==b.x)
            return a.op<b.op;
        return a.x<b.x;
    }
    void cdq(int l,int r){
        if(l==r)
            return ;
        int mid=l+r>>1;
        cdq(l,mid);
        cdq(mid+1,r);
        sort(q+l,q+1+r,cmpb);
        int i;
        for(i=l;i<=r;i++){
            int id=q[i].id;
            if(q[i].op==1&&q[i].a<=mid)
                add(q[i].y,q[i].v);
            if(q[i].op==2&&q[i].a>=mid+1)
                ans[id]+=sum(q[i].y);
            if(q[i].op==3&&q[i].a>=mid+1)
                ans[id]-=sum(q[i].y);
        }
        for(i=l;i<=r;i++){
            if(q[i].op==1&&q[i].a<=mid)
                add(q[i].y,-q[i].v);
        }
    }
    int main(){
        int n,w;
        cin>>n>>w;
        int cnt=0;
        int idx=0;
        while(cin>>n&&n!=3){
            if(n==1){
                int x,y,c;
                scanf("%d%d%d",&x,&y,&c);
                cnt++;
                q[cnt]=node{cnt,x,y,c,1};
            }
            if(n==2){
                int x1,y1,x2,y2;
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                cnt++;
                idx++;
                q[cnt]=node{cnt,x2,y2,0,2,idx};
                ++cnt;
                q[cnt]=node{cnt,x1-1,y1-1,0,2,idx};
                ++cnt;
                q[cnt]=node{cnt,x2,y1-1,0,3,idx};
                ++cnt;
                q[cnt]=node{cnt,x1-1,y2,0,3,idx};
            }
        }
        cdq(1,cnt);
        for(int i=1;i<=idx;i++){
            cout<<ans[i]<<endl;
        }
    }
    View Code
  • 相关阅读:
    fapws3 how to
    some tools
    Subversion文档(中文前6章)
    更改ubuntu root密码
    远程共享访问windows主机
    python下datetime类型的转换
    redis tips
    ubuntu在内存大过4g时会自动打pae补丁
    安装pythondoc
    redis hmset and set is not equviant
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12751161.html
Copyright © 2011-2022 走看看