【Foreign】远行 [LCT]

远行

Time Limit: 20 Sec  Memory Limit: 256 MB

Description

  

Input

  

Output

  

Sample Input

  0
  5 10
  1 4 5
  2 3
  2 5
  2 1
  1 5 3
  1 1 4
  2 3
  2 5
  1 5 2
  2 1

Sample Output

  0
  1
  0
  3
  2
  3

HINT

  

Main idea

  每次连上一条边,询问一个点和其能到达最远的点的距离。

Solution

  由于每次要连上一条边,我们显然使用LCT,然后一个点到达的最远的点必然是树的直径上的端点,我们合并两棵树维护直径的时候,暴力分几种情况讨论一下即可。

Code

  1 #include<iostream>  
  2 #include<algorithm>  
  3 #include<cstdio>  
  4 #include<cstring>  
  5 #include<cstdlib>  
  6 #include<cmath>
  7 #include<vector>
  8 using namespace std;
  9 typedef long long s64;
 10 
 11 const int ONE = 300005;
 12 const int MOD = 1e9+7;
 13 
 14 int Type,n,Q;
 15 int opt,x,y;
 16 int fat[ONE];
 17 int Ans;
 18 
 19 int get()
 20 {
 21         int res=1,Q=1;    char c;
 22         while( (c=getchar())<48 || c>57)
 23         if(c=='-')Q=-1;
 24         if(Q) res=c-48; 
 25         while((c=getchar())>=48 && c<=57) 
 26         res=res*10+c-48; 
 27         return res*Q; 
 28 }
 29 
 30 int Find(int x)
 31 {
 32         if(fat[x]==x) return x;
 33         return fat[x]=Find(fat[x]);
 34 }
 35 
 36 namespace LCT
 37 {
 38         int lc[ONE],rc[ONE],fa[ONE];
 39         int hasRev[ONE];
 40         int L[ONE],R[ONE],dis[ONE],size[ONE];
 41         
 42         void pre()
 43         {
 44             for(int i=1;i<=n;i++)
 45                 fat[i]=L[i]=R[i]=i,
 46                 size[i]=1;
 47         }
 48         
 49         void Update(int x)
 50         {
 51             size[x] = size[lc[x]] + size[rc[x]] + 1;
 52         }
 53         
 54         bool is_real(int x)
 55         {
 56             return (lc[fa[x]]==x || rc[fa[x]]==x);
 57         }
 58         
 59         void tag_rev(int x)
 60         {
 61             hasRev[x]^=1;
 62             swap(lc[x],rc[x]);
 63         }
 64         
 65         void tag_down(int x)
 66         {
 67             if(hasRev[x])
 68             {
 69                 tag_rev(lc[x]);
 70                 tag_rev(rc[x]);
 71                 hasRev[x]=0;
 72             }
 73         }
 74         
 75         void Turn(int x)
 76         {
 77             int y=fa[x],z=fa[y];
 78             int b= x==lc[y]?rc[x]:lc[x];
 79             
 80             fa[y]=x;    fa[x]=z;
 81             if(b) fa[b]=y;
 82             
 83             if(z)
 84             {
 85                 if(y==lc[z]) lc[z]=x;
 86                 else if(y==rc[z]) rc[z]=x;
 87             }
 88             
 89             if(x==lc[y]) rc[x]=y,lc[y]=b;
 90             else lc[x]=y,rc[y]=b;
 91             
 92             Update(y);    Update(x);
 93         }
 94         
 95         void Splay(int x)
 96         {
 97             static int anc[ONE];
 98             int anc_num=0;
 99             anc[++anc_num] = x;
100             for(int i=x; is_real(i); i=fa[i]) anc[++anc_num]=fa[i];
101             while(anc_num>0) tag_down(anc[anc_num--]);
102             while(is_real(x))
103             {
104                 if(is_real(fa[x]))
105                 {
106                     if( (lc[fa[x]]==x) == (lc[fa[fa[x]]]==fa[x]) ) Turn(fa[x]);
107                     else Turn(x);
108                 }
109                 Turn(x);
110             }
111         }
112         
113         void access(int x)
114         {
115             for(int p=x,q=0; p; q=p,p=fa[q])
116             {
117                 Splay(p);
118                 rc[p] = q;
119                 Update(p);
120             }
121         }
122         
123         void make_root(int x)
124         {
125             access(x);    Splay(x);    tag_rev(x);
126         }
127         
128         int dist(int x,int y)
129         {
130             make_root(x);    access(y);    Splay(y);    return size[y]-1;
131         }
132         
133         void link(int x,int y)
134         {
135             int lx,rx,ly,ry;
136             int Fx=Find(x), Fy=Find(y);
137             fat[Fy] = Fx;
138             make_root(x);    fa[x]=y;
139             lx = L[Fx];    rx = R[Fx];    ly = L[Fy];    ry = R[Fy];
140             
141             if(dist(lx,rx) >= dis[Fx]) dis[Fx]=dist(lx,rx), L[Fx]=lx, R[Fx]=rx;
142             if(dist(ly,ry) >= dis[Fx]) dis[Fx]=dist(ly,ry), L[Fx]=ly, R[Fx]=ry;
143             
144             if(dist(lx,ly) >= dis[Fx]) dis[Fx]=dist(lx,ly), L[Fx]=lx, R[Fx]=ly;
145             if(dist(lx,ry) >= dis[Fx]) dis[Fx]=dist(lx,ry), L[Fx]=lx, R[Fx]=ry;
146             if(dist(rx,ly) >= dis[Fx]) dis[Fx]=dist(rx,ly), L[Fx]=rx, R[Fx]=ly;
147             if(dist(rx,ry) >= dis[Fx]) dis[Fx]=dist(rx,ry), L[Fx]=rx, R[Fx]=ry;
148             
149         }
150         
151         void Query(int x)
152         {
153             int Fx=Find(x);
154             Ans = max( dist(L[Fx],x),dist(R[Fx],x) );
155             printf("%d
",Ans);
156         }
157 }
158 
159 int main()
160 {
161         Type=get();
162         n=get();    Q=get();
163         LCT::pre();
164         while(Q--)
165         {
166             opt = get();
167             if(opt == 1)
168             {
169                 x=get();    y=get();
170                 if(Type==1) x^=Ans, y^=Ans;
171                 LCT::link(x,y);
172             }
173             else
174             {
175                 x=get();
176                 if(Type==1) x^=Ans; 
177                 LCT::Query(x);
178             }
179         }
180         
181 }
View Code
原文地址:https://www.cnblogs.com/BearChild/p/6556223.html