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
  • 相关阅读:
    Allegro PCB Design GXL (legacy) 使用slide无法将走线推挤到焊盘的原因
    OrCAD Capture CIS 16.6 导出BOM
    Altium Designer (17.0) 打印输出指定的层
    Allegro PCB Design GXL (legacy) 将指定的层导出为DXF
    Allegro PCB Design GXL (legacy) 设置十字大光标
    Allegro PCB Design GXL (legacy) 手动更改元器件引脚的网络
    magento产品导入时需要注意的事项
    magento url rewrite
    验证台湾同胞身份证信息
    IE8对css文件的限制
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12751161.html
Copyright © 2011-2022 走看看