常用算法总结
1.莫队
1.1莫队算法
对于可以离线的$n$组区间询问,先将序列分为$O(\sqrt{n})$块,再按照左端点属于的块$id$为第一关键字,右端点为第二关键字排序
若能由$[l,r]$的答案$O(k)$得到$[l-1,r]$和$[l,r+1]$的答案,那么就可以在$O(k*n*\sqrt{n})$内得到所有$n$组询问的结果
复杂度证明:左端点每次移动不超过块大小$\sqrt{n}$,右端点每块移动不超过$n$
1.2带修改的莫队算法
分块大小经计算改为$n^{\frac{2}{3}}$
按照左端点所属块为第一关键字排序,右端点所属块为第二关键字排序,时间为第三关键字排序
时间指针移动了$n^{\frac{1}{3}}*n^{\frac{1}{3}}*n$次
右端点指针移动了$n^{\frac{2}{3}}*n$次
左端点指针移动了$n^{\frac{2}{3}}*n$次
总时间复杂度为$O(n^{\frac{5}{3}})$
1.3树上莫队
定义点$u$和点$v$间的路径为$S(u,v)$,根节点为$root$
定义路径的$xor$操作相同的点去掉,不同的点添加(每个点有独立的贡献)
$S(u,v)=S(root,u) xor S(root,v) xor lca(u,v)$
定义$T(u,v)=S(root,u) xor S(root,v)$
那么若上一次询问的是$(u,v)$,这一次询问的是$(curu,v)$,那么
$T(u,v) xor T(curu,v) = S(root,u) xor S(root,v) xor S(root,curu) xor S(root,v)$
$T(curu,v) = T(u,v) xor T(u,curu)$
所以若是询问$(curu,curv)$
$T(curu,curv) = T(u,v) xor T(u,curu) xor T(v,curv)$
对树的$dfs$序分块,可知任何块内俩点距离不超过$size$
2.点分治
考虑求解满足条件的合法点对,那么每次寻找树的重心,那么合法点对只能是
1.$root$与某节点$u$
2.同一棵子树内的节点$u$和$v$
3.俩棵子树内的节点$u$和$v$
对于2我们可以递归考虑,对于1,3对每棵子树取处理,由于重心的性质
去掉重心后剩下的子树中$size$最大值最小
那么分治次数不会超过$log_{2}{n}$
3.cdq分治
考虑离线的修改$&$询问,每次递归将操作分为俩半,再考虑前一半的修改会对后一半产生的贡献,有点类似于归并排序的操作
这样就可以实现降维,将原本的二维偏序变成一维
4.平面点对生成树问题
4.1曼哈顿最小生成树
4.2切比雪夫最小生成树
4.3欧几里得最小生成树

浙公网安备 33010602011771号