zoukankan      html  css  js  c++  java
  • 【模板】LCT

    LCT用来解决树的形态可变的树上操作查询问题

     1 #include<stdio.h>
     2 #include<algorithm>
     3 using namespace std;
     4 struct node{int ch[2],fa,siz;bool rev;};
     5 node sp[200005];
     6 int n,op,fa[200005];
     7 bool isro(int x){return x!=sp[sp[x].fa].ch[0]&&x!=sp[sp[x].fa].ch[1];}
     8 void pushup(int x){sp[x].siz=sp[sp[x].ch[0]].siz+sp[sp[x].ch[1]].siz+1;};
     9 void pushdown(int);
    10 void Pushdown(int);
    11 void rot(int);
    12 void splay(int);
    13 void access(int);
    14 void maker(int x){access(x);splay(x);sp[x].rev^=1;}
    15 void link(int x,int y){maker(x);sp[x].fa=y;splay(x);}
    16 void cut(int x,int y){maker(x);access(y);splay(y);sp[y].ch[0]=sp[x].fa=0;}
    17 int main()
    18 {
    19     scanf("%d",&n);
    20     int i,p,x,y;
    21     for(i=1;i<=n;i++)
    22     {
    23         scanf("%d",&p);
    24         fa[i]=sp[i].fa = min(i+p,n+1);
    25         sp[i].siz = 1;
    26     }
    27     sp[n+1].siz = 1;
    28     scanf("%d",&op);
    29     for(i=1;i<=op;i++)
    30     {
    31         scanf("%d%d",&p,&x); x++;
    32         if(p==1)
    33         {
    34             maker(n+1);
    35             access(x);splay(x);
    36             printf("%d
    ",sp[sp[x].ch[0]].siz);
    37         }
    38         else
    39         {
    40             scanf("%d",&y);
    41             cut(x,fa[x]);
    42             link(x,min(n+1,y+x));
    43             fa[x] = min(n+1,y+x);
    44         }
    45     }
    46     return 0;
    47 }
    48 void rot(int now)
    49 {
    50     int fa=sp[now].fa;int fafa=sp[fa].fa; bool isr=(now==sp[fa].ch[1]);
    51     if(!isro(fa)){sp[fafa].ch[fa==sp[fafa].ch[1]]=now;}
    52     sp[now].fa = fafa;
    53     sp[fa].ch[isr] = sp[now].ch[!isr];
    54     sp[sp[now].ch[!isr]].fa = fa;
    55     sp[now].ch[!isr] = fa;sp[fa].fa = now;
    56     pushup(fa); pushup(now);
    57 }
    58 void pushdown(int now)
    59 {
    60     if(sp[now].rev)
    61     {
    62         int lc = sp[now].ch[0],rc=sp[now].ch[1];
    63         if(lc) sp[lc].rev^=1;
    64         if(rc) sp[rc].rev^=1;
    65         sp[now].ch[0]=rc,sp[now].ch[1]=lc;
    66         sp[now].rev = false;
    67     }
    68 }
    69 void Pushdown(int now)
    70 {
    71     if(!isro(now)) Pushdown(sp[now].fa);
    72     pushdown(now);
    73 } 
    74 void splay(int now)
    75 {
    76     Pushdown(now);
    77     while(!isro(now))
    78     {
    79         if(!isro(sp[now].fa)) rot(now);
    80         rot(now);
    81     }
    82 }
    83 void access(int x)
    84 {
    85     for(int t=0;x;t=x,x=sp[x].fa)
    86     {
    87         splay(x);
    88         sp[x].ch[1] = t;
    89     }
    90 }
    View Code
  • 相关阅读:
    2021 Duilib最新入门教程(二)Duilib编译动态库
    2021 Duilib最新入门教程(一)Duilib简介
    webgl图库选型
    CUDA编程学习记录
    C++时间戳获取
    FFMPEG编译问题记录
    程序员的35岁
    Linux发行版及其目标用户
    服务器关机或重启
    Linux下找出吃内存的方法总结
  • 原文地址:https://www.cnblogs.com/hzs2000/p/6746806.html
Copyright © 2011-2022 走看看