CF842E Nikita and game

题意:每次在树上加一个点,问树上有多少个起点存在与另一点的距离=直径长?

标程:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=300005;
 4 int dep[N],n,fa[N][22],d1,d2,len;
 5 set<int> s1,s2;
 6 set<int> ::iterator t;
 7 int lca(int x,int y)
 8 {
 9     if (dep[x]<dep[y]) swap(x,y); 
10     int del=dep[x]-dep[y];
11     for (int i=20;i>=0;i--)
12       if (del&(1<<i)) x=fa[x][i];
13     if (x==y) return x;
14     for (int i=20;i>=0;i--)
15       if (fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
16     return fa[x][0];
17 }
18 int dis(int x,int y){return dep[x]+dep[y]-2*dep[lca(x,y)];}
19 void init()
20 {
21     for (int j=1;j<=20;j++)//预处理正循环 
22       for (int i=2;i<=n+1;i++)
23         fa[i][j]=fa[fa[i][j-1]][j-1];
24 }
25 int main()
26 {
27     scanf("%d",&n);
28     for (int i=2;i<=n+1;i++) scanf("%d",&fa[i][0]),dep[i]=dep[fa[i][0]]+1;
29    init(); s1.insert(1);
30     for (int i=2;i<=n+1;i++)
31     {
32        d1=(int)s1.size()==0?0:dis(i,*s1.begin());
33        d2=(int)s2.size()==0?0:dis(i,*s2.begin());
34        if (max(d1,d2)>len)
35        {
36            if (d1>len)
37            {
38                for (t=s2.begin();t!=s2.end();++t)
39                  if (dis(i,*t)==d1) s1.insert(*t);
40               s2.clear();    s2.insert(i);
41             }else {
42                 for (t=s1.begin();t!=s1.end();++t)
43                   if (dis(i,*t)==d2) s2.insert(*t);
44                 s1.clear(); s1.insert(i);
45             }
46            len=max(d1,d2);
47         }else if (max(d1,d2)==len)
48         {
49             if (d1==len) s2.insert(i);else s1.insert(i);
50         }
51        printf("%d\n",(int)s1.size()+(int)s2.size());    
52     }
53     return 0;
54 }

易错点:1.lca_init的时候j应该正着枚举。

2.所有直径一定会相交,直径的中点(中心)一定被经过。

题解:set+性质

固定根,直径由离根最远的点的集合s1以及离s1中点最远的点的集合s2中的点组成。

因此维护两个set(vector?),由新加入的点到s1中任意一点的距离和s2中任意一点的距离来判断该点的去向。(可以证明取集合中的任意一点不会影响距离>=原直径的情况)

如果距离>原直径,那么更新此点为s1或s2中的唯一端点,并用被清空的集合更新另一个集合(可以证明有用的端点集合包含于之前的直径端点集合)。

如果距离=原直径,加入s1或s2。

时间复杂度O(nlogn),似乎并不需要set。

猜你喜欢

转载自www.cnblogs.com/Scx117/p/9081691.html