zoukankan      html  css  js  c++  java
  • LCT 动态树 模板

    洛谷:P3690 【模板】Link Cut Tree (动态树)

    /*诸多细节,不注意就会调死去! 见注释。*/
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int MAXN=300099;
    int n,m;
    int fa[MAXN],rev[MAXN],val[MAXN],xr[MAXN],Q[MAXN],ch[MAXN][2];
    bool isroot(int x){ return ch[fa[x]][0]!=x && ch[fa[x]][1]!=x; }
    void Update(int x){ xr[x]=xr[ch[x][0]]^xr[ch[x][1]]^val[x]; }
    bool get(int x){ return ch[fa[x]][1]==x ;}
    void Down(int x){ if(rev[x]){ rev[ch[x][0]]^=1; rev[ch[x][1]]^=1; rev[x]^=1; swap(ch[x][0],ch[x][1]); } }
    void Rotate(int x)
    {
      int old=fa[x],oldf=fa[old],op=get(x);
      if(!isroot(old)) ch[oldf][ch[oldf][1]==old]=x;  //这一条一定要放在改变父子关系之前!在纯Splay中是放在后面的,因为直接看oldf是否为0可知old是否为根。
      ch[old][op]=ch[x][op^1]; fa[ch[x][op^1]]=old; //但这里使用isroot,改变之后就不能判断了!
      ch[x][op^1]=old; fa[old]=x; fa[x]=oldf;
      Update(old); Update(x);
    }
    void Splay(int x)
    {
      int tp=1; Q[1]=x;
      for(int i=x;!isroot(i);i=fa[i]) Q[++tp]=fa[i]; //对于LCT的判断是否是根节点,需要使用isroot,在纯Splay中使用的是fa,不要搞混!
      for(int i=tp;i;i--) Down(Q[i]);
      for(int FA; !isroot(x) ; Rotate(x))
        {
          FA=fa[x];
          if(!isroot(FA))
            Rotate(get(x)==get(FA)?FA:x);
        }
    }
    void Access(int x){ int t=0; while(x){ Splay(x); ch[x][1]=t; Update(x); t=x; x=fa[x]; } } //记得Update
    void Makeroot(int x){ Access(x); Splay(x); rev[x]^=1;}
    void Link(int x,int y){ Makeroot(x); fa[x]=y; }
    void Cut(int x,int y){ Makeroot(x); Access(y); Splay(y); if(ch[y][0]==x) fa[x]=ch[y][0]=0;}
    int Find(int x){ Access(x); Splay(x); while(ch[x][0]) x=ch[x][0]; return x; }
    int main()
    {
      scanf("%d%d",&n,&m);
      for(int i=1;i<=n;i++) scanf("%d",&val[i]) , xr[i]=val[i];
      while(m--)
        { 
          int x,y,op;
          scanf("%d%d%d",&op,&x,&y);
          if(op==0){ Makeroot(x); Access(y); Splay(y); printf("%d
    ",xr[y]); }
          if(op==1){ if(Find(x)!=Find(y)) Link(x,y); }
          if(op==2){ Cut(x,y); }
          if(op==3){ Makeroot(x); val[x]=y; Update(x); }
        }
      return 0;
    }
  • 相关阅读:
    as3 绕中心点旋转
    TweenMax
    As3支持的Html标签一览
    AS3.0 静音和停止所有声音
    as3 如何判断同时按下两个键
    前置窗体
    系统音效控制
    LocalConnection
    as3代码实现调用摄像头
    air 加载网页
  • 原文地址:https://www.cnblogs.com/D-O-Time/p/8040103.html
Copyright © 2011-2022 走看看