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