对于
k=1
k
=
1
,可以直接树形DP求出答案。
对于
k>1
k
>
1
,显然
maxdepth<logkn
m
a
x
d
e
p
t
h
<
log
k
n
。设
dpi,j
d
p
i
,
j
表示
i
i
号点, 为
j
j
时最大的 ,那么状态数是
O(nlogn)
O
(
n
log
n
)
的。
如果我们求出了
dpi,j
d
p
i
,
j
,由于随着
k
k
的减小,每个点的 肯定是单调不降的,所以可以把每个
k
k
要更新哪些点记下来,从大到小枚举 ,更新相关点的
depth
d
e
p
t
h
。由于一个点最多只会被更新
maxdepth
m
a
x
d
e
p
t
h
次,这部分的复杂度为
O(nlogn)
O
(
n
log
n
)
。
然后考虑怎么求
dpx,i
d
p
x
,
i
。将所有儿子按照
dpv,i−1
d
p
v
,
i
−
1
从大到小排序,如果第
k
k
大的值 ,
dpx,i
d
p
x
,
i
就可以取到
k
k
。从大到小枚举 ,找到就退出。复杂度为
n∑ni=2login=O(nlogn)
n
∑
i
=
2
n
log
i
n
=
O
(
n
log
n
)
。
#include<bits/stdc++.h>
using namespace std;
char nc() {
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
void Read(int& x) {
char c=nc();
for(;c<'0'||c>'9';c=nc());
for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-48,c=nc());
}
#define fi first
#define se second
const int N=300010;
const int M=19;
typedef pair<int,int> abcd;
typedef long long ll;
int n,m,x,y;
int t[N<<1],nx[N<<1],h[N],num;
int f[N],c[N],dp[N][M];
int a[N],l,cur[N];
vector<abcd> g[N];
ll Res,Ans;
void Add(int x,int y) {
t[++num]=y;nx[num]=h[x];h[x]=num;
}
bool Cmp(int x,int y) {
return x>y;
}
void Dfs(int x,int y) {
dp[x][1]=n;f[x]=y;
for(int i=h[x];i;i=nx[i])
if(t[i]!=y) Dfs(t[i],x),c[x]=max(c[x],c[t[i]]);
for(int j=2;j<M;j++) {
l=0;
for(int i=h[x];i;i=nx[i])
if(t[i]!=y&&dp[t[i]][j-1]) a[++l]=dp[t[i]][j-1];
sort(a+1,a+l+1,Cmp);
for(int k=l;k>1;k--)
if(a[k]>=k) {
dp[x][j]=k;
break;
}
if(dp[x][j]) g[dp[x][j]].push_back(abcd(x,j));
}
Ans+=++c[x];
}
void Update(int x,int y) {
while(x) {
if(cur[x]>=y) break;
Res+=y-cur[x];
cur[x]=y;
x=f[x];
}
}
int main() {
Read(n);
for(int i=1;i<n;i++) Read(x),Read(y),Add(x,y),Add(y,x);
Dfs(1,0);
for(int i=1;i<=n;i++) cur[i]=1;
Res=n;
for(int k=n;k>1;k--) {
for(int j=0;j<g[k].size();j++) Update(g[k][j].fi,g[k][j].se);
Ans+=Res;
}
cout<<Ans<<endl;
return 0;
}