动态树(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 }