CDQ分治


思想就是分治!

然后就是每次二分区间,然后在分治统计左右区间之后,考虑统计跨越左右区间的数对。

给个模板题 陌上花开。

我们对于这个三维偏序问题,可以考虑CDQ分治。

先对于原序列按照a,b,c排序,这样保证a的单调增。

然后分治,对于每个小区间按照b,a,c排序,这样在右边区间的a大于左边区间的前提下,我们满足b单调增。我们枚举j区间选取的元素,然后取移动指针i保证i位置上的b小于j位置上的b,把i位置上的c加入树状数组。每个j在树状数组上统计一遍答案。这就是全过程。

但是本题有一个问题,它有相同的元素,分治的时候会统计少。

但是我们可以合并相同的元素,就可以了。

会CDQ分治了吗?上代码就懂了。

code:

#include
using namespace std;
#define LL long long
#define file(a) freopen(#a".in","r",stdin),freopen(#a".out","w",stdout)
inline int read(){
	int s=0,f=1;char ch=getchar();
	while(ch<'0'||'9'>1;
	cdq_solve(l,mid);cdq_solve(mid+1,r);
	sort(p+l,p+mid+1,cmp2);
	sort(p+mid+1,p+r+1,cmp2);
	int i=l;
	for(int j=mid+1;j<=r;++j){
		while(i<=mid and p[i].b<=p[j].b){
			c.add(p[i].c,p[i].cnt);++i;
		}
		p[j].ans+=c.find(p[j].c);
	}
	for(int k=l;k