码迷,mamicode.com
首页 > Windows程序 > 详细

AcWing267 莫基亚(CDQ分治)

时间:2020-04-22 13:25:15      阅读:82      评论:0      收藏:0      [点我收藏+]

标签:cstring   style   const   one   静态   using   前缀和   color   oid   

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

 

AcWing267 莫基亚(CDQ分治)

标签:cstring   style   const   one   静态   using   前缀和   color   oid   

原文地址:https://www.cnblogs.com/ctyakwf/p/12751161.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!