ZROI 暑期高端峰会 A班 Day4 树上数据结构

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\) 递减。

动态维护连通性即可。(然而这玩意我还没打过……)

posted @ 2019-08-20 13:56  ATS_nantf  阅读(222)  评论(0编辑  收藏  举报