CDQ 分治
总结
- 偏序问题
- 1D 动态规划优化
- 动态问题转为静态问题
\(\quad\)所有的这些都离不开一个精髓,就是分治处理:先处理左边区间,然后处理左边区间对右边区间的贡献,然后处理右边区间。(后面两项处理根据具体应用调整操作顺序)
\(\quad\)对于偏序问题一般的就是三维偏序,要注意的是一边算贡献,一边作排序,也就是归并排序,不要 sort
。如果是四维偏序的话就再套一个 CDQ,也就是每一个区间,再以 \(b\) 为底,作一次 CDQ 分治,因为还要保证 \(a\) 的顺序,那么需要在 \(b\) 排序的时候打个标记后再排序,最后计算贡献的时候需要满足有标记的前提,最后复杂度应该是 \(O(nlogn^3)\)。
\(\quad\)对于动态规划的优化,一个例子是 \(dp_j=1+dp_i[a_i<a_j][b_i<b_j]\) ,这个东西很明显可以用 CDQ 分治优化成 \(nlogn^2\) 的复杂度,一般作就是 \(n^2\)。
\(\quad\)对于动态问题转为静态问题,其实就是将所有操作放在时间戳上动态操作,那么对于时间来说,所有的操作都是静态的了。这个最经典的例子就是二维数点。
\(\quad\)CDQ 分治的重点就在于减少重复的操作。
\(\quad\)这个就是 CDQ 分治的模板了,不过多赘述。
\(\quad\)对于每一个数考虑作为后面一个数的贡献,如果前面的数删除时间比自己晚,并且比自己大,那么就造成一个贡献,也就是有三个元素 \(time,pos,val\) ,那就是一个三维偏序的题目,最后搞一个后缀和就可以了。
\(\quad\) 二维最长不上升子序列的一个题目。如果我们能算出最优方案的总数和经过每一个炮弹的方案数,那么这个概率就可以直接求了。经过每一个炮弹的最优方案数,我们可以参考最短路中可行点的求法,正反求一遍,最后看是否是最优的,如果是,那么正反的方案数乘起来即可。所以这个题目本质还是求最优方案数。正常的求,应该是 $n^2 $ 的,而且似乎难以优化,但是这个式子和 CDQ 分治特征偏序很像,于是我们发现完全可以用 CDQ 分治来求解。
\(\quad\)这是一道带修改的区间数颜色。区间数颜色的套路要么是莫队,要么就是对于每一个点记录一个 \(pre_j\) ,表示前面和自己同一个颜色的最接近的位置,然后搞个树状数组即可。这个题目用莫队应该是不太行的,那么我们将这个题目进一步抽象为动态二维数点问题,如果是单点修改的话,CDQ 完全可以随便搞,但是可惜是区间修改。不可能一个一个的改,但是我们发现区间覆盖,那么我们想到 odt 的思想,对于连续的颜色我们当成一个点,那么每一次操作相当于删除中间所有的点,然后插入一个点,修改删除的点的左右端点的 \(pre\) ,那么修改的点的复杂度是 \(O(删除点的个数)\) ,每一个点最多被删除一次,每一次操作最多会引进 3 个点,那么总的修改的点就是 \(O(n+m)\) ,那么就可以愉快的套 CDQ 单点修改了。