BYRBT

动态树(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 }
posted @ 2012-07-19 08:20  zhonghaoxi  阅读(1146)  评论(0编辑  收藏  举报
BYRBT