https://codeforces.com/contest/1266/problem/F
特判一些极端如almost-1和集合中仅存两点的情况
大致分两种情况
最终集于某一点或两点
这些点分立不同子树
那么处理每个点为根不同子树的最远距离
显然的,若最远距离为d,可选取[1,d]的距离
1.一点
又可分为
A.1条长度为k,s条长度为k+1的
s+1更新ans[2k+1]
B.s条长度为k的
s更新ans[2k]和ans[2k-1]
2.两点
s1条长度为k的到u点
s2条长度为k的到v点
s1+s2更新 ans[2k]
#include<bits/stdc++.h>
#define file(KSCN) freopen(KSCN".in","r",stdin),freopen(KSCN".out","w",stdout)
using namespace std;
typedef long long ll;
namespace IO{
const int ios=1<<17;
char R[ios],*Rc=R,*RB=R;int pass;
inline int gec(){return(Rc==RB&&(RB=(Rc=R)+fread(R,1,ios,stdin),Rc==RB))?EOF:*Rc++;}
template<typename Tp>inline int read(Tp&A){
static int c,sg;c=gec();sg=0;A=0;
while(!isdigit(c)&&c!=EOF)sg|=(c=='-'),c=gec();
if(c==EOF)return EOF;
while(isdigit(c))A=(A<<3)+(A<<1)+(c^'0'),c=gec();
return A=sg?-A:A,0;
}
inline int read(){return read(pass),pass;}
}
using IO::gec;using IO::read;
const int N=5e6+5;
template<typename T>void cmax(T&a,T b){if(b>a)a=b;}
typedef pair<int,int> par;
vector<int>e[N];
vector< par >a[N];
int du[N],up[N],res[N];
int n;
void DFS1(int x,int FAQ){
for(int to:e[x])if(to!=FAQ)
DFS1(to,x),cmax(du[x],du[to]+1);
}
void DFS2(int x,int upon){
par b[2];
b[0]=make_pair(up[x]=(upon+1),-1);
b[1]=make_pair(-1,-1);
for(int to:e[x])if(du[to]<du[x]){
par su=make_pair(du[to]+1,to);
for(int k=0;k<2;k++)
if(su>b[k])swap(su,b[k]);
}
for(int to:e[x])if(du[to]<du[x])
DFS2(to,b[b[0].second==to].first);
}
int main(){
read(n);
for(int i=1,u,v;i<n;i++){
read(u);read(v);--u;--v;
e[u].push_back(v);
e[v].push_back(u);
}
DFS1(0,-1);
DFS2(0,-1);
vector<int>cur;
for(int x=0;x<n;x++){
cur.clear();
if(up[x])cur.push_back(up[x]);
for(int to:e[x])if(du[to]<du[x])
cur.push_back(du[to]+1);
sort(cur.begin(),cur.end());
for(int dd:cur)if(a[x].empty()||a[x].back().first!=dd)
a[x].push_back(make_pair(dd,1));
else a[x].back().second++;
}
for(int i=1;i<=n;i++)res[i]=1;
int diam=0;
for(int x=0;x<n;x++)cmax(diam,a[x].back().first);
for(int i=1;i<=diam;i++)res[i]=2;
for(int x=0;x<n;x++)cmax(res[1],(int)e[x].size()+1);
for(int x=0;x<n;x++){
int sum=e[x].size();
for(int i=0,ios=a[x].size();i<ios;i++){
cmax(res[(a[x][i].first<<1)-1],sum);
if(i>0)cmax(res[(a[x][i-1].first<<1)+1],sum+1);//>=i & single (i-1)
cmax(res[(a[x][i].first<<1)],sum);
sum-=a[x][i].second;
}
}
for(int x=0;x<n;x++){
for(int to:e[x])if(du[to]<du[x]){
int sum=e[x].size()+e[to].size()-2,c1=0,c2=0;
for(auto QwQ:a[x])if(QwQ.first==du[to]+1)QwQ.second--;
for(auto QwQ:a[to])if(QwQ.first==up[to])QwQ.second--;
while(c1<a[x].size()&&c2<a[to].size()){
int t=min(a[x][c1].first,a[to][c2].first);
cmax(res[t<<1],sum);
if(t==a[x][c1].first)sum-=a[x][c1++].second;
if(t==a[to][c2].first)sum-=a[to][c2++].second;
}
for(auto QwQ:a[x])if(QwQ.first==du[to]+1)QwQ.second++;
for(auto QwQ:a[to])if(QwQ.first==up[to])QwQ.second++;
}
}
for(int i=n-2;i>=1;i--)cmax(res[i],res[i+2]);
for(int i=1;i<=n;i++)printf("%d ",res[i]);
return 0;
}