Tree

联合权值

显然可以枚举中间点,然后做完了。

Code

Cow Politics G

显然的,对于每种颜色,点对中一定包含深度最大的点。

枚举另外一个点即可。

Code

Passable Paths

显然我们需要选择深度最深的点和距离该点最远的点,判断其他点是否在它们的路径上即可。

Code

AHOI2008 聚会

由题意可得要选出 \(u\) 使得 \(dis(u,i)+dis(u,j)+dis(u,k)\) 最小。

首先证明一下 \(u\in\{lca(i,j),lca(i,k),lca(j,k)\}\)

如果 \(u\not\in\{lca(i,j),lca(i,k),lca(j,k)\}\),则将 \(u\) 替换成 \(\{lca(i,j),lca(i,k),lca(j,k)\}\) 中的一个必然能使答案减少。

到这里已经可做了。

实际上我们发现,记 \(3\) 个数分别为 \(u,v,w\),则我们选择 \(u \operatorname{xor} v \operatorname{xor} w\) 为答案(\(u,v,w\) 中有 \(2\) 个相同)。

答案为 \(dep_i+dep_j+dep_k-dep_{lca(i,j)}-dep_{lca(i,k)}-dep_{lca(k,j)}\)

Code

树上询问

\(sz_i\) 表示 \(i\) 的子树大小,\(calc(x,y)\) 表示 \(y\) 的不含 \(x\) 的子树中的大小。

对于询问 \((a,b,c)\) 我们分情况讨论:

\(v=lca(a,b)\)

  • \(c=v\),此时答案为 \(n-calc(a,v)-calc(b,v)\)
  • \(c\in v \rightarrow a\),此时答案为 \(sz_c-calc(a,v)\)
  • \(c\in v \rightarrow b\),此时答案为 \(sz_c-calc(b,v)\)
  • \(c\not\in a \rightarrow b\),此时答案为 \(0\)

Code

rStage5 - Hard Conveyors

\(f_u\) 表示距离 \(u\) 最近的关键点距离 \(u\) 的距离。

dij 可以维护。

问题变为求 \(\min_{ u\in s\rightarrow t}2f_u+dis(s,t)\)

注意后面这个可以简单求得单独拆出,前面的树剖维护之。

Code

Tree Queries

我们令第一次染黑的节点为 \(x\),以 \(x\) 为根建树。

\(a_{i}=\min_{u\in i \leftarrow x}u\)

每次 \(1\) 操作带来的影响有(修改 \(u\)),对于所有 \(p\in\text{black}\)

  • 答案均为 \(\min(a_p,a_u)\)

记录全局最小值即可。

Code

生活在树上(hard version)

记录 \(s_u=\oplus_{i\in1\rightarrow u}w_i\),则题目要求化为是否存在 \(s_u\oplus s_v\oplus s_{lca(u,v)}\oplus k\) 的点

主席树维护之。

Code

Tree Queries

先考虑 \(n^2\) 怎么做。

先特判掉 \(n=1\) 和链。

对于每个点 \(x\),我们令 \(x\) 必选,以 \(x\) 为根 dp。

\(f_u\) 表示 \(u\) 的子树全部确定要几个点,则有

\[f_i=\sum_{v\in son_i}f_v+\max(0,\sum_{v\in son_i}[f_v=0]-1) \]

对于所有 \(i\)\(\min f_i+1\) 即可。

可以通过 D1。

考虑对于一个度数 \(\ge 3\) 的点 \(i\) 进行 dp,答案为 \(f_i\)

为什么这样可行?因为保证了至少有一个点在子树外必选。

Code

TreeMaster

我们可以发现,\(f(x,y)\) 的状态数不会太多。

考虑证明,记 \(d_x\)\(x\) 层的节点数。

  • \(d_x\ge \sqrt{n}\) 时,由于最多只有 \(\dfrac{n}{\sqrt{n}}\le \sqrt{n}\) 层,每层至多调用 \(q\) 次,复杂度 \(q\sqrt q\)
  • 否则由于 \(d_x < \sqrt{n}\),最多有 \(\dfrac{n}{d_x}\) 层,每次调用至多 \(d_x^2\) 次,则状态数是 \(nd_x\le n\sqrt{n}\)

由于 map 太慢,采用如下优化。

  • \(d_x\ge \sqrt{n}\) 时,我们直接暴力,无需记忆化。
  • 由于 \(dep_x=dep_y\),则知道 \(x\),知道 \(y\)\(x\) 层的第几个节点就可以确定 \(y\)(代码中的 \(p_i\) )。
  • 使用数组代替 map。

Code

SDOI2011 消防

发现答案一定在直径上。

之后就是工程题,枚举左端点类似单调队列。

Code

貌似假了/kel(树网的核 93pts)。

NOI2020 超现实树

以下定义链树表示:对于所有节点满足 \(\min(siz_{l_i},siz_{r_i})\le 1\)

发现一些性质:

  • 非链树不能构成链树
  • 如果仅有有限棵链树不能被构成,则仅有有限棵非链树不能被构成。

由上可得非链树无用的。

所以我们将链树的每个节点 \(x\) 分为 \(4\) 类:

  • 只有左子树
  • 只有右子树
  • 左子树大小为 \(1\)
  • 右子树大小为 \(1\)

这些关系构成了一颗四叉树,这样我们用一棵树包含了所有链树的信息。

现在的目标是让有限棵链树不能被构成。

定义 \(g_i\) 表示 \(i\) 节点的子树是否是仅有有限棵链树不能被构成的。

\(g_i=1\) 当且仅当:

  • \(i\) 是某棵链树的儿子。
  • \(i\) 在四叉树上的 \(4\) 个儿子 \(g_i\) 均为 \(1\)

问题转化为求 \(g_1\) 是否等于 \(1\)

时间复杂度 \(\mathcal O(\sum n)\)

Submission

posted @ 2024-05-15 12:58  WhisperingWillow  阅读(12)  评论(0)    收藏  举报