codeforces690C3
很没意思的题
开始看A的人少,点进去发现简单题。。。
直接动态维护一下倍增数组
新的直径只可能是原直径或者新加入点和原来直径两个端点构成的路径
代码如下:
#include<bits/stdc++.h> #define N 2000005 using namespace std; int dep[N],f[N][18],n,x; inline int lca(int x,int y){ if (dep[x]<dep[y]) swap(x,y); for (int i=17;~i;i--) if (dep[f[x][i]]>=dep[y]) x=f[x][i]; if (x==y) return x; for (int i=17;~i;i--) if (f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i]; return f[x][0]; } inline int dis(int x,int y){return dep[x]+dep[y]-2*dep[lca(x,y)];} int main(){ scanf("%d",&n);dep[1]=1;int cnt=1; int d1=1;int d2=1;int ans=0; n--;while (n--){ scanf("%d",&x);int i=x;x=++cnt; dep[x]=dep[i]+1; f[x][0]=i; for (int j=1;j<18;j++) f[x][j]=f[f[x][j-1]][j-1]; if (dis(x,d1)>dis(x,d2)) swap(d1,d2); if (dis(x,d2)>ans) ans=dis(x,d2),d1=x; printf("%d ",ans); } return 0; }