分治
什么是分治?
- 把一个较大规模的问题分成若干个较小规模的问题。
-
小规模的问题与原问题不同(根号分治)。
-
小规模的问题与原问题相同(对数分治)。
二分就是一种对数分治的方法。
cdq 分治 & 线段树分治
修改和询问的整体分治也被称为 cdq 分治。
要求:修改对询问具有可加性。
主要操作:
-
将所有操作离线。
-
对于区间 \([l,r]\),选取中点 \(mid\),只统计左修改对右的贡献。
-
递归 \([l, mid], [mid + 1, r]\)。
无题号 函数
三种操作,加入一个一次函数,删除一个函数,求 \(x_0\) 处所有函数的最大值,\(n\le 10^6\)。
第一眼看上去是线段树分治(),但是要求用 cdq 做。
考虑维护一个下凸壳,插入好做,删除不好做。
考虑先从左往右扫一遍统计只有 + 的贡献。
然后从 \(r\rightarrow mid+1\),把删除改成增加,倒着扫,从 \(r\rightarrow mid + 1\),用平衡树维护下凸壳。
- 如何用平衡树维护下凸壳
注意到斜率是单增的,考虑维护这个东西。

他肯定是包含了一个斜率区间,然后切掉了两端直线的部分。
那么我们维护两个东西:凸包上的斜率,交点的 \(x\) 坐标。
然后平衡树找到斜率之后,直接向前向后枚举被删除掉的斜率,维护这两个东西就行。
讲了这么久,最后告诉我 cdq 过不去()
正解是线段树分治套平衡树维护凸包(),这玩意儿是 \(O(n\log^2 n)\) 的。
可以在节点时就把斜率排序好, 每个节点维护一个凸包就行,\(O(n\log n)\)。
CTSC2016 时空旅行
一棵树,每个节点上有一个集合 \(S_u = \{(x, c)\}\),并且每个节点一定是其父亲增减一个数对得到。
给出多次 \(u, x_0\),问 \(\min\limits_{(x,c)\in S_u} (x - x_0) ^2 + c\)。
把式子展开,发现和上面那道题其实一样,但加了一个持久化的操作。
可以把删除抽象成 dfs 序上删了一段,可以想到段数只会是点数带个常数,然后和上个题一模一样。
P5787 二分图 /【模板】线段树分治
简单板子题。
把边的存在区间拍上去再可撤销并查集就做完了。
P4585 [FJOI2015] 火星商店问题
首先先对时间线段树分治,然后对每个节点的答案再汇总。
考虑每个节点弄一个可持久化 01 Trie,然后 \([l, r]\) 中的商店的最大值就是 \([1, r] - [1, l - 1]\) 的最大值(在 01 Trie 的节点上)。
复杂度两只 log。
整体二分
如果需要很多次二分并且可以离线,那么就可以用整体二分来解决。
P3332 [ZJOI2013] K大数查询
发现如果只有一次二分很简单,直接做就可以,但是复杂度 \(O(nq)\)。
考虑整体二分,同时二分所有问题。
假设我们现在二分到 \([l, r)\),那么我们检验 \(mid\)。
按时间扫一遍当前的操作集合。
如果遇到修改,我们把 \(c\) 在 \([l, mid)\) 之间的先统计贡献,用线段树维护。
那么对于询问,我们按正常的二分的思路,查当前 \(mid\) 是否合法。
如果答案在 \([l, mid]\) 之间,加入左集合;否则减去 \(p\) 这个位置有多少个处于 \([l, mid)\) 的,然后扔到右集合。
然后把修改操作全部按 \(c\) 分到左右集合即可。
P3527 [POI2011] MET-Meteors
简单板子题,看题解吧。

浙公网安备 33010602011771号