昨天晚上写了一道最裸的cdq分治的题陌上花开,自己做出来的,感觉又有了一定的领悟。感觉其实cdq分治就相当于主席树的用处,主席树又叫函数式线段树,顾名思义可以拿来当一个函数用,相当于建出来之后就一劳永逸了,来一个询问解决一个。但是有些题目并不要求在线,所以并不需要把一整个主席树都建出来,而是每次都在线地去找它的前缀,然后cdq分治保证了每个点都有不超过logn个前缀,并且在计算i的时候它的前缀已经全部处理完了。
所以说cdq分治是很节约空间的。可以把O(nlogn)的空间强力降到O(n)。网上很多人说cdq的内存是nlogn的,我真的很奇怪,整个程序都没有动态开内存,全局数组开了多少自己还不知道吗。。
比如说陌上花开一题,每个花有三个属性,对每个花求有多少花三个属性都不超过它。常规解法是排序之后树状数组套treap或者主席树,然后扫描。cdq分治的话分治套树状数组就可以了,先按a排序,每一次分治用划分的思想将b划分开,然后c用树状数组来求前缀和。
这道题稍微难一点。我开始的时候想了一下数据结构解法,应该是外面一个线段树里面一个主席树。线段树的话涉及区间修改需要打标记,比较麻烦,可以用支持区间修改区间查询的树状数组来代替。由于时间不是很充足,只是自己YY了一下,不知道能不能实现。
分治的做法比较给力。首先其实这个应该叫整体二分,并不是传统的cdq分治。一般的cdq分治不断划分就行了,但是这个整体二分在划