好厉害。
特判 \(k = 1\)。首先经过观察,我们可以按照 \(k\) 的奇偶性讨论:
- \(k\) 为偶数,有一个中心点挂了若干条长度为 \(\frac{k}{2}\) 的链。
- \(k\) 为偶数,有两个中心点,两边挂了若干条长度为 \(\frac{k}{2}\) 的链;
- \(k\) 为奇数,有一个中心点挂了若干条长度为 \(\frac{k + 1}{2}\) 的链和至多一条长度为 \(\frac{k - 1}{2}\) 的链。
根据上面我们有 \(ans_k \ge ans_{k + 2}\)。最后取个后缀 \(\min\) 即可。接下来考虑如何处理这 \(3\) 种贡献。
我们可以把每个点的每棵子树挂的最长链预处理出来。然后按照这个长度扫描线。设当前点 \(u\) 出现次数为 \(b_u\)。
对于第一种贡献,可以直接让 \(ans_{2i} \gets b_u\)。
对于第二种贡献,我们要讨论 \(u\) 的所有邻居。维护 \(c_u\) 表示 \(u\) 的所有儿子的 \(b_u\) 的最大值。然后让 \(ans_{2i} \gets \max(b_u + c_u - 2, b_u + b_{fa_u} - 2)\) 即可。\(-2\) 是因为两棵子树互相重复贡献了。
对于第三种贡献,若 \(u\) 是在长度 \(i\) 中第一次出现,有 \(ans_{2i + 1} \gets b_u\),否则 \(ans_{2i - 1} \gets b_u\)。
时间复杂度 \(O(n)\)。
code
// Problem: F. Almost Same Distance
// Contest: Codeforces - Codeforces Global Round 6
// URL: https://codeforces.com/contest/1266/problem/F
// Memory Limit: 256 MB
// Time Limit: 5000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))
using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;
const int maxn = 1000100;
int n, f[maxn], g[maxn], h[maxn], a[maxn], b[maxn], c[maxn], fa[maxn];
bool vis[maxn];
vector<int> G[maxn], vc[maxn];
void dfs(int u, int fa) {
for (int v : G[u]) {
if (v == fa) {
continue;
}
::fa[v] = u;
dfs(v, u);
vc[f[v] + 1].pb(u);
if (f[v] + 1 > f[u]) {
g[u] = f[u];
f[u] = f[v] + 1;
} else if (f[v] + 1 > g[u]) {
g[u] = f[v] + 1;
}
}
}
void dfs2(int u, int fa) {
for (int v : G[u]) {
if (v == fa) {
continue;
}
h[v] = max(h[u] + 1, f[v] + 1 == f[u] ? g[u] + 1 : f[u] + 1);
vc[h[v]].pb(v);
dfs2(v, u);
}
}
void solve() {
scanf("%d", &n);
for (int i = 1, u, v; i < n; ++i) {
scanf("%d%d", &u, &v);
G[u].pb(v);
G[v].pb(u);
}
for (int i = 1; i <= n; ++i) {
a[1] = max(a[1], (int)G[i].size() + 1);
}
dfs(1, -1);
dfs2(1, -1);
for (int i = n; i; --i) {
for (int u : vc[i]) {
++b[u];
c[fa[u]] = max(c[fa[u]], b[u]);
a[i * 2] = max({a[i * 2], b[u] + b[fa[u]] - 2, b[u] + c[u] - 2, b[u]});
if (!vis[u]) {
a[i * 2 + 1] = max(a[i * 2 + 1], b[u]);
}
a[i * 2 - 1] = max(a[i * 2 - 1], b[u]);
vis[u] = 1;
}
for (int u : vc[i]) {
vis[u] = 0;
}
}
for (int i = n; i; --i) {
a[i] = max({a[i], a[i + 2], 1});
}
for (int i = 1; i <= n; ++i) {
printf("%d ", a[i]);
}
}
int main() {
int T = 1;
// scanf("%d", &T);
while (T--) {
solve();
}
return 0;
}