首先说明,CDQ分治与整体二分都是离线算法
CDQ分治:
流程:
1.我们要解决一系列问题,这些问题一般包含修改和查询操作,可以把这些问题排成一个序列,用一个区间[L,R]表示。
2.分。递归处理左边区间[L,M]和右边区间[M+1,R]的问题。
3.治。合并两个子问题,同时考虑到[L,M]内的修改对[M+1,R]内的查询产生的影响。即,用左边的子问题帮助解决右边的子问题。
经典问题:三维偏序
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=100010;
const int K=200010;
struct node{
int x,y,z,ans,w;
}a[N],b[N];
int tot,cnt[K],k,n;
bool cmpx(node a,node b){
if(a.x==b.x){
if(a.y==b.y) return a.z<b.z;
return a.y<b.y;
}
return a.x<b.x;
}
bool cmpy(node a,node b){
if(a.y==b.y) return a.z<b.z;
return a.y<b.y;
}
int c[K];
int lowbit(int x){
return x&(-x);}
void add(int i,int x){
for(;i<=k;i+=lowbit(i))
c[i]+=x;
}
int sum(int i){
int res=0;
for(;i>0;i-=lowbit(i))
res+=c[i];
return res;
}
void cdq(int l,int r){
if(l==r) return;
int mid=(l+r)>>1;
cdq(l,mid);cdq(mid+1,r);
sort(a+l