zoukankan      html  css  js  c++  java
  • 省选前集训 lca

    LCA
    描述
    加边,删边,动态求两点的lca

    删边以后要恢复以前的跟,因为lca与树根有关,不能随意旋转树

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 #define maxn 100020
      7 
      8 int fa[maxn],child[maxn][2],rev[maxn];
      9 int n,m;
     10 int stack[maxn],tops = -1;
     11 
     12 inline bool isroot(int x){
     13     return (child[fa[x]][0] != x && child[fa[x]][1] != x);
     14 }
     15 inline void reverse(int x){
     16     rev[x] ^= 1;
     17     swap(child[x][0],child[x][1]);
     18 }
     19 inline void pushdown(int x){
     20     if ( rev[x] ) {
     21         if ( child[x][0] ) reverse(child[x][0]);
     22         if ( child[x][1] ) reverse(child[x][1]);
     23         rev[x] = 0;
     24     }
     25 }
     26 inline void rotate(int x){
     27     int t = child[fa[x]][1] == x;
     28     int y = fa[x] , z = child[x][1 - t];
     29     fa[x] = fa[y];
     30     if ( !isroot(y) ) child[fa[x]][child[fa[x]][1] == y] = x;
     31     fa[y] = x;
     32     child[x][1 - t] = y;
     33     if ( z ){
     34         fa[z] = y;
     35     }
     36     child[y][t] = z;
     37 }
     38 inline void splay(int x){
     39     stack[++tops] = x;
     40     for (int i = x ; !isroot(i) ; i = fa[i]) stack[++tops] = fa[i]; 
     41     while ( ~tops ) pushdown(stack[tops--]);
     42     while ( !isroot(x) ){
     43         int y = fa[x] , z = fa[y];
     44         if ( (!((child[z][0] == y) ^ (child[y][0] == x))) && !isroot(y) ) rotate(y);
     45         else rotate(x);
     46         if ( isroot(x) ) break;
     47         rotate(x);    
     48     }
     49 }
     50 inline int access(int x){
     51     int t = 0;
     52     for (;x;x = fa[x])
     53         splay(x) , child[x][1] = t , t = x;
     54     return t;
     55 }
     56 inline void makeroot(int x){
     57     access(x);
     58     splay(x);
     59     reverse(x);
     60 }
     61 inline void link(int x,int y){
     62     makeroot(y);
     63     fa[y] = x;
     64 }
     65 inline int findroot(int x){
     66     access(x);
     67     splay(x);
     68     pushdown(x);
     69     while ( child[x][0] ) x = child[x][0] , pushdown(x);
     70     return x;
     71 }
     72 inline void cut(int x,int y){
     73     int R = findroot(x);
     74     makeroot(y);
     75     access(x);
     76     splay(x);
     77     child[x][0] = fa[y] = 0;
     78     makeroot(R);
     79 }
     80 inline int getans(int x,int y){
     81     if ( findroot(x) != findroot(y) ) return -1;
     82     access(x);
     83     return access(y);
     84 }    
     85 void print(){
     86     for (int i = 1 ; i <= n ; i++) cout<<i<<" fa "<<fa[i]<<" child "<<child[i][0]<<" "<<child[i][1]<<endl;
     87 }
     88 int main(){
     89     freopen("lca.in","r",stdin);
     90     freopen("lca.out","w",stdout);
     91     scanf("%d %d",&n,&m);
     92     for (int i = 1 ; i <= m ; i++){
     93         int t,x,y;
     94         scanf("%d %d %d",&t,&x,&y);
     95         if ( t == 1 ) link(x,y);
     96         else if ( t == 2 ){
     97             if ( fa[x] == y ) cut(x,y);
     98             else cut(y,x);
     99         }
    100         else printf("%d
    ",getans(x,y));
    101     //    cout<<i<<endl;
    102     //    print();
    103     }    
    104     return 0;
    105 }
  • 相关阅读:
    生成器
    各种表达式
    迭代器
    闭包函数及装饰器
    名称空间及作用域
    函数的嵌套
    函数对象
    OpenSSL Heartbleed “心脏滴血”漏洞简单攻击示例
    PHP函数usort是咋回事?还能当后门?
    CVE-2017-7269—IIS 6.0 WebDAV远程代码执行漏洞分析
  • 原文地址:https://www.cnblogs.com/zqq123/p/5309008.html
Copyright © 2011-2022 走看看