【复习笔记】根号算法总结
由于我根号算法实在是太菜,所以有了这么篇不是很靠谱的总结= =
如果有问题直接戳我或者留言就好>.<
莫队
理想莫队信息:维护一个子集的信息,支持\(O(a)\)插入一个元素,\(O( b )\)删除一个元素,无法比直接暴力更高效地合并
例如:给出一个点集,多次询问点集的一个子集的信息
普通莫队:考虑右端点O(n)变化过程中,左端点限制在一个根号块内,也就是每次移动不超过根号,总复杂度为\(O(nsqrt(m)+m)\)
一个卡常小trick:奇数块正着排,偶数块反着排常数小一半
由于莫队是对于值域暴力维护,而修改次数是\(O(nsqrt(m))\),查询次数是\(O(m)\),因此对于值域进行根号分治维护复杂度可以去掉线段树的log(log-log平衡此时不如1-sqrt平衡)
普通莫队常见题:小Z的袜子
二次离线莫队:将莫队当做是O( nsqrt(m) )次查询区间中满足特定特征的性质的数的某个信息
如果这个信息具有可减性,可以差分 考虑差分后变成O(nsqrt(m) )次查询前缀中满足特定特征的性质的数的某个信息 此时插入次数\(O(n)\)而查询次数\(O(nsqrt(m))\) 把插入的复杂度往上提,查询O(1)就可以做到更优秀的复杂度
树上莫队:
1.树上两条链的信息差分成两段到根的路径(四维降成二维)此时使用普通莫队即可
2.连通块直接分块
3.对括号序分块(此时可以处理子树信息或链信息 链信息需要特判LCA)
分块
静态分块:大部分针对在线处理,预处理时对于块信息\(O(n\sqrt{n})\)与块与块之间的信息\(O(n)\)预处理
常见用法:区间众数/逆序对
势能分块:一道很牛的题 [Ynoi2019] 美好的每一天~ 不连续的存在
定义势能\(f(i)\)表示\(1\text{~}i\)加入\(i\)的合并次数 因为启发式合并 所以总数是nlogn 所以按照\(f(i)\)加权分块 每增量\(\sqrt{nlog}\) 每个块暴力启发式合并
因为\([1,r]\)加入\(r+1\)的势能一定是大于\([l,r]\)加入\(r+1\)的势能的 因此复杂度正确
此时分块复杂度分析为\(O(FN+totF/F)\) 因此一个块内取\(\sqrt{totF}=\sqrt{nlog}\)
根号重构分块:比较常见的就是分块维护凸包之类的东西,如果边角块变化就重构,不然可以直接打tag快速处理答案(比如凸包就可以使用two pointer去掉log)
根号平衡
平凡根号平衡:\(\sum s_i =n\)此时不同的\(s_i\)不超过\(\sqrt n\)(度数/出现次数)
常见用法:光速幂/度数分块/数论分块/分块区间和等等