zoukankan      html  css  js  c++  java
  • [loj6038]「雅礼集训 2017 Day5」远行 lct+并查集

    给你 n 个点,支持 m 次操作,每次为以下两种:连一条边,保证连完后是一棵树/森林;询问一个点能到达的最远的点与该点的距离。强制在线。

    n3×10^n≤3×10^5 ,m5×10^m≤5×10^5 。


    我们知道与一个点距离最大的点为任意一个直径的两个端点之一。

    两棵树之间连一条边,新树直径的两个端点一定为第一棵树直径的两个端点和第二棵树直径的两个端点这四者中之二。

    于是我们可以用lct和并查集来维护树的直径的两个端点。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<cmath>
     5 #include<cstdio>
     6 #include<algorithm>
     7 #define fa(x) t[x].fa
     8 #define s(x,y) t[x].son[y]
     9 #define maxn 305050
    10 using namespace std;
    11 inline int read() {
    12     int x=0,f=1;char ch=getchar();
    13     for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
    14     for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
    15     return x*f;
    16 }
    17 int type;
    18 int n,q;
    19 struct LCT {
    20     int f[maxn],px[maxn],py[maxn];
    21     int find(int x) {return x==f[x]?f[x]:f[x]=find(f[x]);}
    22     struct Tree {int son[2],fa,w,rev;}t[maxn];
    23     bool isrt(int x) {return s(fa(x),0)!=x&&s(fa(x),1)!=x;}
    24     void pushup(int x) {t[x].w=t[s(x,0)].w+t[s(x,1)].w+1;}
    25     void pushdown(int x) {
    26         if(t[x].rev) {
    27             swap(s(x,0),s(x,1));
    28             t[s(x,0)].rev^=1;t[s(x,1)].rev^=1;
    29             t[x].rev=0;
    30         }
    31     }
    32     void push(int x) {
    33         if(!isrt(x)) push(fa(x));
    34         pushdown(x);
    35     }
    36     void rotate(int x) {
    37         int y=fa(x),z=fa(y);
    38         int l=s(y,1)==x,r=l^1;
    39         if(!isrt(y)) s(z,s(z,1)==y)=x;
    40         fa(x)=z;fa(y)=x;fa(s(x,r))=y;
    41         s(y,l)=s(x,r);s(x,r)=y;
    42         pushup(y);pushup(x);
    43     }
    44     void splay(int x) {
    45         push(x);
    46         while(!isrt(x)) {
    47             int y=fa(x),z=fa(y);
    48             if(!isrt(y)) {
    49                 if(s(z,0)==y^s(y,0)==x) rotate(x);
    50                 else rotate(y);
    51             }
    52             rotate(x);
    53         }
    54     }
    55     void access(int x) {for(int pre=0;x;pre=x,x=fa(x)) {splay(x);s(x,1)=pre;pushup(x);}}
    56     void makert(int x) {access(x);splay(x);t[x].rev^=1;}
    57     int dis(int u,int v) {makert(u);access(v);splay(v);return t[v].w;}
    58     void link(int u,int v) {
    59         int fx=find(u),fy=find(v);
    60         if(fx!=fy) {
    61             makert(u);fa(u)=v;
    62             int a=0,b,c;
    63             if(dis(px[fx],py[fx])>a) a=dis(px[fx],py[fx]),b=px[fx],c=py[fx];
    64             if(dis(px[fy],py[fy])>a) a=dis(px[fy],py[fy]),b=px[fy],c=py[fy];
    65             if(dis(px[fx],py[fy])>a) a=dis(px[fx],py[fy]),b=px[fx],c=py[fy];
    66             if(dis(px[fx],px[fy])>a) a=dis(px[fx],px[fy]),b=px[fx],c=px[fy];
    67             if(dis(py[fx],px[fy])>a) a=dis(py[fx],px[fy]),b=py[fx],c=px[fy];
    68             if(dis(py[fx],py[fy])>a) a=dis(py[fx],py[fy]),b=py[fx],c=py[fy];
    69             f[fx]=fy;px[fy]=b;py[fy]=c;
    70         }
    71     }
    72     int query(int u) {
    73         int x=find(u);
    74         return max(dis(px[x],u),dis(py[x],u));
    75     }
    76 }lct;
    77 int main() {
    78     type=read();
    79     n=read(),q=read();
    80     for(int i=1;i<=n;i++) lct.f[i]=lct.px[i]=lct.py[i]=i;
    81     int lastans=0;
    82     while(q--) {
    83         int t=read();
    84         if(t==1) {
    85             int u=read()^(lastans*type),v=read()^(lastans*type);
    86             lct.link(u,v);
    87         }
    88         else {
    89             int u=read()^(lastans*type);
    90             lastans=lct.query(u)-1;
    91             printf("%lld
    ",lastans);
    92         }
    93     }
    94 }
    View Code
  • 相关阅读:
    485串口接线
    mvc3 升级mvc5
    VB连接ACCESS数据库,使用 LIKE 通配符问题
    VB6 读写西门子PLC
    可用的 .net core 支持 RSA 私钥加密工具类
    解决 Win7 远程桌面 已停止工作的问题
    解决 WinForm 重写 CreateParams 隐藏窗口以后的显示问题
    解决安装 .net framework 发生 extracting files error 问题
    CentOS7 安装配置笔记
    通过特殊处理 Resize 事件解决 WinForm 加载时闪烁问题的一个方法
  • 原文地址:https://www.cnblogs.com/wls001/p/10182914.html
Copyright © 2011-2022 走看看