版权声明:欢迎转载蒟蒻博客,但请注明出处: https://blog.csdn.net/LPA20020220/article/details/86490855
洛谷传送门
Codeforces传送门
题意翻译
给出一棵有根树,对于每个节点 ,定义一个无穷序列 ,其中 表示以 为根节点的子树中到 的距离恰好为 的点的个数, ,现在对每个点 ,希望求出一个值 ,使得对于任意 , ,对于任意
输入输出格式
输入格式:
第一行一个整数 ,表示树的节点个数 接下来 行,每行两个整数, , ,表示 之间有一条连边
输出格式:
行,每行一个整数,第 行表示 时对应的
输入输出样例
输入样例#1:
4
1 2
2 3
3 4
输出样例#1:
0
0
0
0
输入样例#2:
4
1 2
1 3
1 4
输出样例#2:
1
0
0
0
输入样例#3:
4
1 2
2 3
2 4
输出样例#3:
2
1
0
0
解题分析
长链剖分模板题。没什么好说的…
注意转移重儿子的时候写假了还能过138个点…
代码如下:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <cstdlib>
#include <algorithm>
#define R register
#define IN inline
#define W while
#define gc getchar()
#define MX 1005000
template <class T>
IN void in(T &x)
{
x = 0; R char c = gc;
for (; !isdigit(c); c = gc);
for (; isdigit(c); c = gc)
x = (x << 1) + (x << 3) + c - 48;
}
int n, cnt;
struct Edge {int to, nex;} edge[MX << 1];
int buf[MX << 2], *dp[MX], *pt = buf;
int dep[MX], head[MX], son[MX], ans[MX];
IN void add(R int from, R int to)
{edge[++cnt] = {to, head[from]}, head[from] = cnt;}
void DFS(R int now, R int fa)
{
for (R int i = head[now]; i; i = edge[i].nex)
{
if (edge[i].to == fa) continue;
DFS(edge[i].to, now);
if (dep[edge[i].to] > dep[son[now]]) son[now] = edge[i].to;
}
dep[now] = dep[son[now]] + 1;
}
IN void nw(R int now) {dp[now] = pt; pt += dep[now] + 2;}
void DP(R int now, R int fa)
{
int mx = 0;
dp[now][0] = 1;
if (!son[now]) return;
dp[son[now]] = dp[now] + 1;
DP(son[now], now); ans[now] = ans[son[now]] + 1; mx = dp[now][ans[now]];
for (R int i = head[now]; i; i = edge[i].nex)
{
if (edge[i].to == fa || edge[i].to == son[now]) continue;
nw(edge[i].to);
DP(edge[i].to, now);
for (R int j = 0; j < dep[edge[i].to]; ++j)
{
dp[now][j + 1] += dp[edge[i].to][j];
if (dp[now][j + 1] > mx) ans[now] = j + 1, mx = dp[now][j + 1];
else if (dp[now][j + 1] == mx && ans[now] > j + 1) ans[now] = j + 1;
}
}
if (dp[now][ans[now]] == 1) ans[now] = 0;
}
int main(void)
{
in(n); int foo, bar;
for (R int i = 1; i < n; ++i)
in(foo), in(bar), add(foo, bar), add(bar, foo);
DFS(1, 0); nw(1);
DP(1, 0);
for (R int i = 1; i <= n; ++i) printf("%d\n", ans[i]);
}