八刀氵台
容易从标题中看出整篇的内容。
在 OI-wiki 的 算法基础 这一栏中就可以看到这篇文章说的东西。
可能比我理解的更深一点吧。
啥也不会,但是这种普及组的知识点还是需要记录一下的。
不过还好,NOI 不考普及题。不然就爆零了。
使用一些极为简单的问题大致阐述分治的思想即可。
分治的话最经典的貌似就是 CDQ 了。
大致思想就是讲问题分成两个规模相似的问题,然后分别求解,最后考虑两边相互的贡献。
貌似有点抽象,主要还是因为这东西也分好几种。
虽然本质都一样,切开,递归求解两边,合并。
区间可合并信息
例如查询区间最小值,查询区间和。
先考虑其中性质最好的吧,区间可容斥问题,例如单点加,区间和。
首先对时间轴进行分治。
考虑可以从中间分开,左右分别递归求解。
然后需要解决的是前半部分的修改对后半部分的查询的影响。
直接双指针扫一扫就结束了。
严谨分析一下复杂度。
容易发现复杂度和序列长度完全没有关系。
设共有 \(m\) 次修改/查询。
则有 \(T(n, m) = T(a, \frac{m}{2}) + T(n - a, \frac{m}{2}) + O(n)\),其中 \(n\) 表示在当前时间区间内的修改/查询的数量。
虽然是不均等分裂,但是容易发现 \(m\) 每次变为原来的一般,而且 \(n\) 的和不变。
所以得到 \(T(n, m) = O(n \log m)\)。
代入原问题则可得复杂度为 \(T(m, m) = O(m \log m)\)。
上述复杂度分析适用于大多数的 CDQ 分治以及整体二分。
虽然很没用而且很废话但是还是写在上面吧。
当然,上面是对时间轴做的分治。
然而,参考一个远古答辩。
我们发现这个问题是一个二维平面上的离线问题。
那么,可以切割时间轴的话,也自然可以切割另一个坐标轴了。
于是我们考虑,直接对序列进行分治。
考虑从中间把序列分开,左右分别递归求解。
同时可以发现,由于维护的是区间可合并信息,所以如果有询问横跨了左右两边,可以直接分裂开来,然后简单合并即可。
然而每次暴力分裂问题复杂度很假。
所以考虑,当我们的查询覆盖了整个区间的时候就停下来。
因为这个也是可以很方便的维护的。
接下来的话,考虑对于时间轴维护连续段即可。
每次归并连续段,单点查询。
容易发现时间复杂度 \(O(m \log m)\)。
然而空间复杂度是 \(O(m \log m)\)。
首先发现这东西其实长得有点像线段树分治。
所以根据闲话 Day9的方法确实可以把空间优化成线性。
然而。。。。
我们发现这东西其实长得更像一个线段树。
或者说,就是一个线段树,只不过离线下来同时处理了所有的问题。
经过仔细考虑,即可发现线段树的本质。
线段树其实是动态维护了一个 CDQ分治 的递归树。
考虑单点修改,每次只需要把影响到的 \(O(\log n)\) 个节点的信息更新一下即可。
然后使用线段树正常解决问题的过程其实相当于是在沿着时间轴做扫描线的过程。
这样考虑的话,其实线段树可以做的区间可容斥问题都可以转成 CDQ。
当然,回归到最开始的思路。
如果我们硬要切割时间轴呢。
也就是说,我们想要对序列进行分治。
把这个过程的内层分治建成一个递归树,然后动态维护一下。
然后我们发现这个问题变成了单点修改,区间历史版本和。
这也就是为什么可以离线的历史版本和问题基本上都用扫描线解决了。
本质上就只是切割的坐标轴不同。
至此,可以简单的将分治的实现方式归个类。
我们现在将对时间轴分治这类分治(指的是长的类似的,和时间轴本身没关系)称为第一类分治。
长得像线段树的分治称为第二类分治。
接下来就是区间不可容斥问题。
考虑一下单点修改,区间最小值。
事实上和区间可容斥问题差不多。
大致区别就是,可容斥问题可以简单的转化成前缀和问题,然后就可以使用第一类分治解决。
然而可重复贡献问题不行。
但是容易发现,如果只是做区间修改/查询的话,其实可以直接使用第二类分治。
在多数情况下这两类分治的复杂度是相同的。
再考虑的话其实这两种分治分别有点像树状数组和线段树。
分别是前缀信息和区间信息。
在可容斥信息中这两个没啥区别,但是不可容斥信息就能看出来问题了。
然而,第二类的复杂度时空同阶,第一类空间至少稳定线性。
虽然第二类确实可以把复杂度也优化成线性,但是常数极大实现困难很没用。
事实上,递归树怎么建都可以,没必要每次均等分裂,甚至没必要分两个部分。
例如我们可以像树状数组一样建递归树,跑 CDQ。
这样的话区间不可容斥问题就可以做到 \(O(n \log^2 n)\) 了。
更加值得一提的是,常数极大。
话说,还没见过像 kdt 一样跑分治的。
虽然理论上是可行的,但是很离谱。
当然,区间最小值还有一个性质是可重复贡献。
利用这个性质有些时候也可以降低复杂度。然而我不会。
上面说的区间不可容斥问题包括不可重复贡献的,例如最大子段和。
区间不可合并信息
其实这东西说的并不是完全无法合并的那种东西。
要是一个大规模的问题无法化解成若干小问题,那么只能说这个问题不可解。
或者至少是不会解。
这里的不可合并指的是合并的复杂度和左右长度成线性关系,或者是某个定值一类的。
例如,区间每种数出现次数的平方和。
如果我们把询问拆开去跑分治的话,最后就会面临合并复杂度过高的问题。
因此,对于大多数区间不可合并信息,都很难直接用分治法做。
分块这种平衡复杂度的东西不在讨论范围之内。
所以考虑一个性质良好的特殊情况,子树问题。
仍然考虑小Z的袜子这个问题。
现在放到树上,每个节点有一个值,每次询问子树内每种数出现次数的平方和。
这个其实就是非常喜闻乐见的线段树合并了。
复杂度直接做到 \(O(n \log n)\),和序列上的问题复杂度差距巨大。
至于为什么会有这种差距,也比较显然。
相当于是已经给定了一个递归树的形态了。
我们只需要去处理全局的答案即可。
过程中每个节点的答案都记录下来,那么就可以应付完询问了。
当然,这种东西可解也需要前提,那就是可以启发式合并。
也就是可以以任意形态递归来求解全局问题。
类似的问题还有区间逆序对。
这些问题基本都是归约矩阵乘法的。
本来我以为这一类能够归约矩阵乘的序列问题放到树上都是可以简单解决的。
然而二维数点不可以。
大致原因就是,二维数点属于可容斥问题。
所以我们可以将原问题做成前缀和。
前缀和询问就满足树上询问的形式了,所以直接可以用树上问题做双向归约。
结论就是拍到子树上能够化简的问题需要满足不可快速合并,但是可以启发式合并。
最近脑子有点乱。上面的东西写的很意识流。
学分治学的。
大致的,当维数增多的时候,考虑递归分治变成原问题是一个很麻烦的事情,有的时候不好想明白。
而且,关于可解问题和不可解问题的界限还是不明晰。
两个长得很像的问题,一个可以简单求解,另一个却归约矩乘。
可能接下来几天还会去考虑上面的问题?