距离一个点最远的点一定是直径的一个端点。
考虑运用这个原理,每次维护一下直径端点即可。
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 using namespace std; 8 9 #define N 500010 10 #define M 20 11 12 int dep[N<<2],f[M][N<<2]; 13 14 int n; 15 int q,k; 16 int v=1,m=2; 17 18 int main() 19 { 20 dep[1]=dep[2]=dep[3]=1; 21 n=4; 22 scanf("%d",&q); 23 while (q--) 24 { 25 scanf("%d",&k); 26 k--; 27 f[0][n]=f[0][n+1]=k; 28 dep[n]=dep[n+1]=dep[k]+1; 29 for (int i=1;i<M && f[i-1][f[i-1][n]];i++) 30 f[i][n]=f[i][n+1]=f[i-1][f[i-1][n]]; 31 if (dep[n]>dep[v]) 32 v=n,++m; 33 else if (dep[n]+dep[v]>m) 34 { 35 int x=v,y=n; 36 for (int i=0;i<M && dep[x]!=dep[y];i++) 37 if ((dep[x]-dep[y]) & (1<<i)) 38 x=f[i][x]; 39 for (int i=M-1;i>=0;i--) 40 if (f[i][x]!=f[i][y]) 41 x=f[i][x],y=f[i][y]; 42 if (dep[n]+dep[v]-(dep[f[0][x]]<<1)>m) 43 ++m; 44 } 45 n+=2; 46 printf("%d ",m); 47 } 48 return 0; 49 }