题解:CF1527D MEX Tree
某模拟赛 T1,赛后发现爆标(题解是
我们发现不含
对于含 爆标了!!
code
#include<bits/stdc++.h>
using namespace std;
#define N 200005
int n, f[N], siz[N];
long long ans[N];
bool book[N];
vector<int> mp[N];
inline dfs(int x, int y) {
f[x] = y, siz[x] = 1;
for(int i = mp[x].size() - 1; ~i; --i) {
int to = mp[x][i];
if(to ^ y) {
dfs(to, x);
if(!x) ans[0] += 1ll * (siz[to] - 1) * siz[to] >> 1;
siz[x] += siz[to];
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while(t--) {
cin >> n;
if(n == 1) {
puts("0 0");
continue;
}
for(int i = n - 1; i; --i) {
int u, v;
cin >> u >> v;
mp[u].push_back(v), mp[v].push_back(u);
}
dfs(0, 0);
int l = 1, r = 0, now = 1, as = 1;
while(f[now]) book[now] = 1, now = f[now];
book[now] = 1, book[0] = 1;
while(book[as]) ++as;
siz[0] -= siz[now];
ans[1] = 1ll * siz[0] * (siz[now] - siz[1]);
int sz = siz[0];
for(int i = mp[0].size() - 1; ~i; --i) {
int to = mp[0][i];
if(to ^ now) sz -= siz[to], ans[1] += 1ll * sz * siz[to];
}
for(int i = as; i < n; i = as) {
int ii = i;
while(!book[f[ii]]) book[ii] = 1, ii = f[ii];
book[ii] = 1;
if(f[ii] == l) {
while(book[as]) ++as;
ans[i] = 1ll * siz[r] * (siz[l] - siz[i]);
l = i;
} else if(f[ii] == r) {
while(book[as]) ++as;
ans[i] = 1ll * siz[l] * (siz[r] - siz[i]);
r = i;
} else break;
}
ans[as] = 1ll * siz[l] * siz[r];
for(int i = 0; i <= n; ++i) {
printf("%lld ", ans[i]);
ans[i] = book[i] = siz[i] = f[i] = 0;
mp[i].clear();
}
putchar('\n');
}
return 0;
}