根号分治的本质就是结合两个暴力,使得复杂度得到了均摊。
题目:Problem – 1207F – Codeforces
现在有两种暴力,第一种是根据题目模拟,修改操作时间复杂度 $O(1)$,查询操作时间复杂度 $O\left( \frac{n}{x} \right)$。
第二种暴力是针对查询操作优化的,也就是定义 $b$ 数组为下标模 $i$ 的结果为 $j$ 的数的和是多少,这样修改的时候是 $O(n)$ 的,查询是 $O(1)$ 的。
我们发现,这两种暴力是两个极端。第一种暴力修改极快,查询操作是一个反比例函数,随着 $x$ 的增大而减小。
第二种暴力查询极快,但是修改没有优化,也即是不管 $x$ 为多少都需要 $o(n)$。
所以我们考虑以第二种暴力来应对数据小的情况,第一种应对数据大的情况。
这样使得复杂度尽量均摊。
我们需要找到一个临界值,小于(或小于等于)这个临界值的用第二种暴力,否则用第一种暴力。
我们可以发现,我们需要找到一个方法使得查询时间复杂度和修改时间复杂度尽量相同,那么我们假设临界值为 $p$,我们希望 $x$ 为临界值的时候的时间复杂度之差 $|p – \frac{n}{p}|$ 越小越好,所以取最小值 $0$。
那么就是 $p = \frac{n}{p}$,可以得出 $p = \sqrt{ n }$。
这就是为啥叫根号分治。