FBI Warning:本文含有大量人类的本质之一。
你经历过绝望吗?
[ZJOI2007]捉迷藏
询问树上最远黑点对。
动态边分治可以比点分治少一个 \(\log\)。
bzoj3730
咕了。
[ZJOI2015]幻想乡战略游戏
动态维护一棵树的带权重心。每个点度数 \(\le 20\)。
暴力:从根往最重的跳,能跳就跳。
动态点分治加速即可。
边分治?链分治?
边分治和点分治很像,找一条边使得剩下部分尽量平衡。
不过直接这样会被菊花图卡掉。
然后就要……用某些方法变成二叉树。
咕了。这么重要的东西,肯定回来补的。
[Ynoi2012]D1T3
开 幕 雷 击
每次查询时,考虑在点分树上找到深度最浅的点,满足这个点被保留区间点 \(x\) 所在连通块包含。暴力跳即可。
那么把根固定下来统计。具体就是问子树中对于点满足它到根的路径上有 \(\min\ge l,\max\le r\),不同的颜色数有多少。
询问离线按根分类,对每个根按 \(l\) 排序,CDQ 分治即可。
floj 307 不可知圆环/CF1010F
一棵树,可以随意删边,问使得 \(1\) 所在连通块大小为 \(k\) 的方案数。
明显可以 DP。\(f_{x,i}\) 表示 \(x\) 的子树,删到 \(x\) 所在连通块恰好为 \(i\) 方案数。
写成生成函数的形式:\(F_u(x)=x\prod(F_v(x)+1)\)。
树链剖分。对于每条重链:
\(F_u(x)\) 表示考虑重儿子的生成函数,\(A_u(x)\) 表示不考虑重儿子的生成函数再乘上 \(x\)。
对于重链底端,\(F_u(x)=A_u(x)\)。否则 \(F_u(x)=A_u(x)(F_v(x)+1)\)。
对于一条重链分治求。对于两条重链之间暴力。复杂度应该是三个 \(\log\)。
[Ynoi2012]D2T3
对于度数小于等于根号的点,暴力。
对于度数大于根号的点,点数不会太多。
这种做法是根号的。
套路:对每个点,只维护轻儿子。修改时只有轻边的父亲需要动态维护。
由于轻边只有 \(\log\) 条,复杂度就是两个 \(\log\)。
又是链分治
咕了。
百度必应边分治和链分治去了……
UOJ191
发现明显是个上凸包。
然后把操作看成是操作树,末尾加一个元素看作走向一个儿子,末尾删除一个儿子看作回溯。
就是问一条路径的上凸包中,某个点处的值。
然后就是询问一条链上的上凸包。可以启发式合并。(不知道能不能李超线段树……)
复杂度应该是两个 \(\log\)。
???
\(n\) 个点的树,\(q\) 次操作,修改单点点权或者询问最大权值连通块。
动态 DP。就是子树内包含/不包含根的。没了。
???
一棵树,每个点可以用 \(a_u\) 代价选中子树中所有叶子。每次单点修改 \(a\),询问选中所有叶子的最小代价。
DP。\(f_u\) 表示……
动态 DP 套路,重链剖分。没了。
LCT
太棒了终于有会的了
动态DP
太棒了终于又有会的了
注意的是也可以用 LCT 维护。神奇的是,这里 LCT 跑得更快。
???
\(n\) 个人(\(0\) 到 \(n-1\)),第 \(i\) 个人手上有个 \(a_i\)
最开始有个数 \(x=0\)。从 \(0\) 到 \(n-1\),每个人可以选择是否变成 \((x+a_i)\bmod n\)
游戏结束后第 \(x\) 个人获胜
每个人采取如下策略:只有当变了 \(x\) 能必胜,且不变不必胜的情况下,他才会变动 \(x\)。
\(q\) 次操作,每次修改 \(a_i\),询问谁获胜。
\(n,q\le 10^5\)
首先肯定只会最多一个人动手。因为如果两个人动手,前面那个人就没有必胜了,矛盾。
而且动了手后 \(x\) 一定会变成 \(i\)。
\(i\) 朝 \((i-a_i)\bmod n\) 连边。当 \((i-a_i)\bmod n\ge i\) 时毫无意义,因为 \(x\) 一定是移动后能必胜才变的,所以对于前 \(i\) 个人不可能变出 \(\ge i\) 的数。
这形成了一个森林(大点往小点连边)。
只考虑有 \(0\) 的那棵树。
\(f_x\) 表示如果从 \(0\) 一路变到 \(fa_x\),\(x\) 是否会选择把它变成 \(x\)。
然后就是个开枪游戏(?),LCT 维护动态 DP 即可。
Codechef Pushflow
\(n\) 个点的图,每个点最多属于一个简单环(点仙人掌?),边有边权。
\(m\) 次操作,询问两点之间最大流,或者修改一个边权。
\(n,m\le 10^5\)
最大流就是最小割。
最小割要么是切环上两条边,要么是切一条树边。
对于环边,肯定有一条是最小边,那么把它删掉,并把它的边权加到这个环上其它边的边权上。
那么此时剩下的肯定是一棵树,就是求链上最小值了。
修改边权,如果是树边,直接搞;如果是环边,就需要更新最小值和树形态了。
用 LCT 可以做到 \(O(m\log n)\)。(大常数……)
WineDAG's Prevention
\(n\) 个点的树 \(q\) 次操作,单点修改点权,翻转路径上点权,询问路径和、最大值、最小值。
\(n,q\le 10^5\)
考虑 LCT。对每一块用一棵 Splay 维护形态,另一棵权值 Splay 维护权值,次序一一对应。
复杂度 \(O(q\log n)\)。
CF1137F
给一棵树,每个点有一个优先级,初始为自己的标号。……
先把最大标号作为根。
考虑 \(x\) 和 \(y\) 哪个先被删。
如果 \(x\) 是 \(y\) 的祖先,明显 \(y\) 先被删。
否则就比较子树最大值,小的那个先被删。
由于每次会把一个点改成最大值+1,考虑 LCT 维护 access 连续段,等价于换根,并且整体修改到原来跟上一段路径的子树最大值。
然后就是查询全局排名。
???
三部分点 A,B,C,各有 \(n_1,n_2,n_3\) 个点。
其中 AB 构成一棵树,AC 构成一棵树,A 之间的点没有连边。
随机 \(i,j\) 把 \(B_1\) 到 \(B_i\),\(C_1\) 到 \(C_j\) 删了,问 \(A\) 仍然联通的概率。
\(n_i\le 10^5\)
发现 \(i\) 递增的时候,使得 \(A\) 联通的 \(j\) 递减。
动态维护连通性即可。(然而这玩意我还没打过……)