标签:trie 包含 删除 怎么 rod 随机 树状数组 优化 森林
LCT
链分治(树剖)
点/边分治
建出点分树,每个子树用堆维护:①最远的\(1\)距离;②它的每个儿子的①堆顶;
全局维护每棵子树②堆最大的两个值,每次修改暴力改就可以。
时间复杂度\(O(n \log^2n)\)(基本动态点分都是\(\log^2\)以上的复杂度……然而仍然随便过\(10^5\),小常数可能性微存?)。
每个点维护一个深度数据结构(这里树状数组就可以),询问的时候子树直接查,父亲递归上去。
每个点对每个儿子单独维护一个树状数组,因为计算的时候要差分。
考虑重心在树上转移的过程,如果不是到父亲,显然是走到\(size_y>\frac{size_x}{2}\)的一个子树。
可以用点分树优化这个过程。
每次扫一下所有儿子,找到最优的,直接跳到分治中心递归即可。
由于重心是凸的,可以保证正确性。
考虑查询的时候,在点分树上找到最浅的一个点\(y\),满足这个点被保留\([l,r]\)后被\(x\)的连通块包含,则所有\([l,r]\)间的点都在\(y\)的子树里。
对于以\(y\)为分治中心的每个点\(i\),维护从\(i\)到\(y\)路径上编号最大和最小的点\(\max_i,\min_i\)。
发现点\(i\)在连通块内的充要条件是\([\min_i,\max_i] \subseteq [l,r]\),转化成了经典二维数点问题。
一个比较显然的暴力是直接背包,每对点会在\(lca\)处产生一次复杂度,总复杂度\(O(n^2)\)。
观察dp式子\(f_{x,j}=\prod_{y \in son_x}^{\sum_k=j}(f_{y,k}+[k=0])\),发现很像一个卷积。
考虑链分治,树上轻儿子\(size\)和是\(O(n\log n)\)级别。
所以对于一条重链,可以先递归求出它链上所有轻儿子的生成函数,然后就变成了序列上问题,这个可以分治fft解决。总复杂度\(O(n\log^3n)\),不过常数很小。
著名毒瘤题。(我写这题的时候splay和treap都被卡常了,最后换了压缩trie才过)
比较naive的想法是根号分治+\(\log\)数据结构。
发现对于每个大点,修改次数均摊\(O(\sqrt n)\)次,询问次数只有均摊\(O(1)\)次,用分块代替\(\log\)数据结构,可以做到\(O(n\sqrt n)\)。
,
换一种思路,对每个点维护轻儿子,则不在这个集合里的只有重儿子,本身和父亲。修改的时候暴力跳重链就行了。
单次修改\(\log^2n\),询问\(\log n\)。(实际上有一个\(\log\)的做法)
比较naive的想法是离线建出操作树,问题变成了求链上叉积最大值。然而直接维护凸包是\(\log^3 n\)的(树剖+线段树/set+凸包上二分)。
观察在重链上跳的过程,发现除了最后一次,每次都是重链上的一个前缀,那么可以离线询问,对每条重链直接暴力维护前缀凸包,两部分都是\(\log^2n\)。
考虑序列上怎么做,发现就是一个经典的线段树题。
把它搬到树上,发现就是一个动态dp,做完了。
每轮游戏只会有一个人动手,且动手前后一定是\(i-a_i => i\)。
如果\(i\geq a_i\),则\(i\)向\(i-a_i\)连边,整个结构形成了一个森林。
所有叶节点为\(f_i=1\),中间节点为\(\max(0, 1-\sum_{j\in son_i}f_j\),lct维护动态dp即可。
最大流=最小割。
最小割如果是环边,就一定会把环上的最小值删掉,不妨把它删掉并把它的权值加到环上的其他边上,lct维护即可。
圆方树也可以做,合理设置边权即可。
建两棵splay分别维护权值和形态,保证中序遍历一一对应,修改直接在权值splay上做就好了。
发现修改操作和lct中的换根操作一模一样,直接lct维护就行了。需要一个树状数组来维护额外信息。
枚举\(i\),显然\(j\)具有单调性,可以双指针。对于\(AB\)间的每条边,边权设为删除时间,加入\(AC\)边的时候删除\(AB\)间最早删除的边即可,lct随便维护。
不知道为什么这种水题讲了那么久。
标签:trie 包含 删除 怎么 rod 随机 树状数组 优化 森林
原文地址:https://www.cnblogs.com/suwakow/p/11375070.html