zoukankan      html  css  js  c++  java
  • 【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
  • 相关阅读:
    VBoxManage命令详解
    十条nmap常用的扫描命令
    2015-12-16 第八天笔记整理-第二部分
    2015-12-13 第八天笔记整理-第一部分
    2015-12-06 第七天课程笔记
    2015-12-04 学习笔记整理
    2015-11-22 第五天
    选择控制语句和循环结构
    数据类型和运算符
    常用DOS指令
  • 原文地址:https://www.cnblogs.com/BearChild/p/6556223.html
Copyright © 2011-2022 走看看