zoukankan      html  css  js  c++  java
  • 动态树(link cut tree)——模板

    题目背景为八中2002。

    link cut tree代码量小,比树链剖分好写多了,而且复杂度也比树链剖分低,但由于splay的存在,常数比较大,但不失为一种十分优秀的数据结构。

     

    View Code
      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 
      5 using namespace std;
      6 
      7 const int maxn=200010;
      8 
      9 int n,m;
     10 
     11 struct node
     12 {
     13     int l,r,f,size;
     14     bool rt;
     15     node()
     16     {
     17         l=r=f=size=0;
     18         rt=false;
     19     }
     20 }z[maxn];
     21 
     22 void update(int now)
     23 {
     24     z[now].size=z[z[now].l].size+z[z[now].r].size+1;
     25 }
     26 
     27 void rot_l(int now)
     28 {
     29     int a=z[now].r;
     30     z[now].r=z[a].l;
     31     z[a].l=now;
     32     z[z[now].r].f=now;
     33     if (z[now].rt)
     34     {
     35         z[now].rt=false;
     36         z[a].rt=true;
     37     }
     38     else
     39     {
     40         if (z[z[now].f].l==now) z[z[now].f].l=a;
     41         else z[z[now].f].r=a;
     42     }
     43     z[a].f=z[now].f;
     44     z[now].f=a;
     45     update(now);
     46     update(a);
     47 }
     48 
     49 void rot_r(int now)
     50 {
     51     int a=z[now].l;
     52     z[now].l=z[a].r;
     53     z[a].r=now;
     54     z[z[now].l].f=now;
     55     if (z[now].rt)
     56     {
     57         z[now].rt=false;
     58         z[a].rt=true;
     59     }
     60     else
     61     {
     62         if (z[z[now].f].l==now) z[z[now].f].l=a;
     63         else z[z[now].f].r=a;
     64     }
     65     z[a].f=z[now].f;
     66     z[now].f=a;
     67     update(now);
     68     update(a);
     69 }
     70 
     71 void splay(int now)
     72 {
     73     while (!z[now].rt)
     74     {
     75         int f=z[now].f;
     76         int ff=z[f].f;
     77         if (z[f].rt)
     78         {
     79             if (z[f].l==now) rot_r(f);
     80             else rot_l(f);
     81         }
     82         else
     83         {
     84             if (z[ff].l==f && z[f].l==now)
     85             {
     86                 rot_r(ff);
     87                 rot_r(f);
     88             }
     89             if (z[ff].r==f && z[f].r==now)
     90             {
     91                 rot_l(ff);
     92                 rot_l(f);
     93             }
     94             if (z[ff].l==f && z[f].r==now)
     95             {
     96                 rot_l(f);
     97                 rot_r(ff);
     98             }
     99             if (z[ff].r==f && z[f].l==now)
    100             {
    101                 rot_r(f);
    102                 rot_l(ff);
    103             }
    104         }
    105     }
    106 }
    107 
    108 void access(int now)
    109 {
    110     int p1=now;
    111     int p2=0;
    112     do
    113     {
    114         splay(p1);
    115         z[z[p1].r].rt=true;
    116         z[p2].rt=false;
    117         z[p1].r=p2;
    118         z[p2].f=p1;
    119         update(p1);
    120         p2=p1;
    121         p1=z[p1].f;
    122 
    123     }while (p1!=0);
    124 }
    125 
    126 void cut(int now)
    127 {
    128     access(now);
    129     splay(now);
    130     z[z[now].l].rt=true;
    131     z[z[now].l].f=0;
    132     z[now].l=0;
    133     update(now);
    134 }
    135 
    136 void join(int now,int f)
    137 {
    138     access(now);
    139     z[now].f=f;
    140 }
    141 
    142 int main()
    143 {
    144     freopen("bounce.in","r",stdin);
    145     freopen("bounce.out","w",stdout);
    146 
    147     scanf("%d",&n);
    148     n++;
    149     for (int a=2;a<=n;a++)
    150     {
    151         int now;
    152         scanf("%d",&now);
    153         z[a].rt=true;
    154         z[a].size=1;
    155         if (now+a<=n) z[a].f=now+a;
    156         else z[a].f=1;
    157     }
    158     z[1].rt=true;
    159     z[1].size=1;
    160     scanf("%d",&m);
    161     for (int a=1;a<=m;a++)
    162     {
    163         int opt;
    164         scanf("%d",&opt);
    165         if (opt==1)
    166         {
    167             int now;
    168             scanf("%d",&now);
    169             now+=2;
    170             access(now);
    171             splay(now);
    172             printf("%d\n",z[z[now].l].size);
    173         }
    174         else
    175         {
    176             int now,nowv;
    177             scanf("%d%d",&now,&nowv);
    178             now+=2;
    179             cut(now);
    180             if (now+nowv<=n) join(now,now+nowv);
    181             else join(now,1);
    182         }
    183     }
    184 
    185     return 0;
    186 }
  • 相关阅读:
    第五天——编码进阶(三)
    vue系列---------vuejs基础学习3.0
    前端随心记---------vuejs基础学习2.2
    前端随心记---------HTML5+CSS系列5.0
    前端随心记---------Ajax
    前端随心记---------前后端验证用户名案例(php,mysql结合)
    前端随心记---------MySQL
    前端随心记---------PHP
    vue系列---------vuejs基础学习2.1
    前端随心记---------HTML5+CSS系列4.0
  • 原文地址:https://www.cnblogs.com/zhonghaoxi/p/2598580.html
Copyright © 2011-2022 走看看