胡扯两句——CDQ分治

之前听大神讲过CDQ分治大概是个什么东西,但是一直还没有真正去搞过。今天稍微看了一下,写点自己的理解。

首先CDQ分治有两个条件。

条件1:可以分成两个独立互不影响的问题(这里的“独立”是指将前面区间的影响处理掉后,后面与前面都成为了新的相同问题)

条件2:允许离线(据说最近流行强制在线。。。如果这样只好去写恶心的数据结构了)。

CDQ分治在可以使用的情况下很多高级数据结构题可以用CDQ分治干过去,不仅时空优越而且易于调试(虽然我并不觉得很好调试

大体思路是将问题不断分成两个子问题,用前一个子问题中的修改操作去更新后一个子问题,这样之后就得到了两个互不影响的子问题,达到分治的目的。

贴一道版题代码:BZOJ 1176

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define lowbit(x) ((x)&-(x))
 4 struct data{
 5        int v,x,y,d,f,pos;
 6        bool operator <(const data& w)const{
 7        if(x!=w.x) return x<w.x;
 8        if(y!=w.y) return y<w.y;
 9        return pos<w.pos;
10     }
11 }a[200005],tmp[200005];
12 int s,w,t[2000005],cnt,ans[200005];
13 int read(int& x){
14     x=0; int f=1,a=getchar();
15     while(a<'0' || a>'9') {if(a=='-') f=-1; a=getchar();}
16     while(a>='0' && a<='9') x=x*10+a-'0',a=getchar(); x*=f;
17 }
18 inline void add(int y,int x){for(int i=y;i<=w;i+=lowbit(i)) t[i]+=x;}
19 inline int query(int y){int ret=0; for(int i=y;i;i-=lowbit(i)) ret+=t[i]; return ret;}
20 void CDQ(int l,int r){
21     if(l==r) return;
22     int mid=(l+r)>>1,t1=l-1,t2=mid; //这里写错调了老半天
23     for(int i=l;i<=r;i++){
24         if(a[i].v<=mid && !a[i].pos) add(a[i].y,a[i].d);
25         if(a[i].v>mid && a[i].pos) ans[a[i].pos]+=query(a[i].y)*a[i].f;
26     }
27     for(int i=l;i<=r;i++)
28         if(a[i].v<=mid && !a[i].pos) add(a[i].y,-a[i].d);
29     for(int i=l;i<=r;i++)
30         if(a[i].v<=mid) tmp[++t1]=a[i];
31         else tmp[++t2]=a[i];
32     for(int i=l;i<=r;i++) a[i]=tmp[i];
33     CDQ(l,mid); CDQ(mid+1,r);
34 }
35 int main(){
36     read(s); read(w); int t,x,y,d,x1,x2,y1,y2;
37     while(1){
38         read(t);
39         if(t==1){
40             read(x); read(y); read(d);
41             a[++cnt]=(data){cnt,x,y,d,1,0};
42         }else if(t==2){
43             read(x1); read(y1); read(x2); read(y2); ++ans[0];
44             a[++cnt]=(data){cnt,x1-1,y1-1,0,1,ans[0]};
45             a[++cnt]=(data){cnt,x2,y2,0,1,ans[0]};
46             a[++cnt]=(data){cnt,x1-1,y2,0,-1,ans[0]};
47             a[++cnt]=(data){cnt,x2,y1-1,0,-1,ans[0]};
48         }else break;
49     }
50     sort(a+1,a+1+cnt);
51     CDQ(1,cnt);
52     for(int i=1;i<=ans[0];i++)
53     printf("%d
",ans[i]);
54     return 0;
55 }
原文地址:https://www.cnblogs.com/enigma-aw/p/5980848.html