Atcoder abc291
https://atcoder.jp/contests/abc291/tasks
Ex - Balanced Tree
给定n点树T
构建n点新的有根树R满足
lca(u,v) 在 T中的path(u,v)上
所有非根点u, 2sz[u] <= sz[fa[u]]
(题目保证有解)
输出R
n 1e5
2s
1024mb
我的思路
显然 性质2说明所有向下分叉至少是2叉
性质一怎么用?
如果在R中u是v的祖先节点
lca(u,v) = u
u一定在路径T(u,v)上
…
v1,v2 在 u 两个分支, lca(v1,v2) = u
u要在(v1,v2) 路径上
…
如果u选作 R的根, 那么在T 中u的一个分支中的所有点一定在R中也是同一个分支中
所以要在T中找一个点,使得它的所有分支的点数 * 2 都 <= n
注意到 任意点最多一个分支 点数 * 2 > n, 所以沿着这个方向走,这个方向的点数单调递减
而 …-u-(v > n/2), 则从选择u移动到选择v: (…-u < n/2)-v-(…)
所以总可以找到一个点
那么选作为根以后,直接按它切开,剩余的连通块就是子问题了
但是如何 优化每次寻找?
还是直接暴力复杂度就够了
注意到第一次是O(n)
那么第二次每个块 <= n/2, 而总复杂度依然是O(n)
所以 O(n log n) 暴力就没了
写完以后发现,不一定是 所有二叉,因为 两点的话 ,叶子是1, 带叶子的一个是2也是合法的,所以二不二叉不重要,重要的是所有分叉 <= n/2
代码
https://atcoder.jp/contests/abc291/submissions/41836648
1 |
|
总结
不愧是 黄题的 G和Ex, 没啥难度