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;
}

 

posted @ 2018-08-11 19:29  longint  阅读(87)  评论(0编辑  收藏  举报