【codeforces379F】 New Year Tree

距离一个点最远的点一定是直径的一个端点。
考虑运用这个原理,每次维护一下直径端点即可。

 

 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\n",m);
47     }
48     return 0;
49 }

 

posted @ 2016-04-06 20:06  Yangjiyuan  阅读(171)  评论(0编辑  收藏  举报