## bzoj 2243 树链剖分

2013-11-19 16:21

  1 //By BLADEVIL
2 type
3     rec                                 =record
4         sum, left, right, succ, pred    :longint;
5         lazy                            :longint;
6     end;
7
8 var
9     n                                   :longint;
10     pre, other                          :array[0..2000100] of longint;
11     last                                :array[0..1000100] of longint;
12     m                                   :longint;
13     color                               :array[0..1000100] of longint;
14     father, size, max_son               :array[0..1000100] of longint;
15     dep, top, a, num                    :array[0..1000100] of longint;
16     tot                                 :longint;
17     flag                                :array[0..1000100] of boolean;
18     l                                   :longint;
19     t                                   :array[0..4000100] of rec;
20
21 procedure swap(var a,b:longint);
22 var
23     c                                   :longint;
24 begin
25     c:=a; a:=b; b:=c;
26 end;
27
28 procedure connect(x,y:longint);
29 begin
30     inc(l);
31     pre[l]:=last[x];
32     last[x]:=l;
33     other[l]:=y;
34 end;
35
36 procedure dfs(x:longint);
37 var
38     q, p                                :longint;
39 begin
40     size[x]:=1;
41     q:=last[x];
42     while q<>0 do
43     begin
44         p:=other[q];
45         if not flag[p] then
46         begin
47             father[p]:=x;
48             flag[p]:=true;
49             dfs(p);
50             inc(size[x],size[p]);
51             if size[max_son[x]]<size[p] then max_son[x]:=p;
52         end;
53         q:=pre[q];
54     end;
55 end;
56
57 procedure make(x,t,depth:longint);
58 var
59     q, p                                :longint;
60 begin
61     inc(tot);
62     num[x]:=tot;
63     top[x]:=t;
64     a[tot]:=color[x];
65     dep[x]:=depth;
66     if (max_son[x]<>0) and (not flag[max_son[x]]) then
67     begin
68         flag[max_son[x]]:=true;
69         make(max_son[x],t,depth);
70     end;
71     q:=last[x];
72     while q<>0 do
73     begin
74         p:=other[q];
75         if not flag[p] then
76         begin
77             flag[p]:=true;
78             make(p,p,depth+1);
79         end;
80         q:=pre[q];
81     end;
82 end;
83
84 procedure build(x,l,r:longint);
85 var
86     mid                                 :longint;
87 begin
88     t[x].left:=l; t[x].right:=r;
89     if l=r then
90     begin
91         t[x].sum:=1;
92         t[x].succ:=a[l];
93         t[x].pred:=a[l];
94         exit;
95     end;
96     mid:=(l+r) div 2;
97     build(x*2,l,mid);
98     build(x*2+1,mid+1,r);
99     t[x].succ:=t[x*2].succ;
100     t[x].pred:=t[x*2+1].pred;
101     if t[x*2].pred=t[x*2+1].succ then
102         t[x].sum:=t[x*2].sum+t[x*2+1].sum-1 else
103         t[x].sum:=t[x*2].sum+t[x*2+1].sum;
104 end;
105
106 procedure init;
107 var
108     i                                   :longint;
109     x, y                                :longint;
110
111 begin
113     for i:=1 to n do read(color[i]);
114     for i:=1 to n-1 do
115     begin
117         connect(x,y);
118         connect(y,x);
119     end;
120     flag[1]:=true;
121     dfs(1);
122     fillchar(flag,sizeof(flag),false);
123     flag[1]:=true;
124     make(1,1,1);
125     build(1,1,n);
126 end;
127
128 procedure change(x,l,r,z:longint);
129 var
130     mid                                 :longint;
131 begin
132     if t[x].lazy<>0 then
133     begin
134 t[x*2].lazy:=t[x].lazy;
135         t[x*2].sum:=1;
136         t[x*2].succ:=t[x].lazy;
137         t[x*2].pred:=t[x].lazy;
138         t[x*2+1].lazy:=t[x].lazy;
139         t[x*2+1].sum:=1;
140         t[x*2+1].succ:=t[x].lazy;
141         t[x*2+1].pred:=t[x].lazy;
142         t[x].lazy:=0;
143     end;
144     if (t[x].left=l) and (t[x].right=r) then
145     begin
146         t[x].lazy:=z;
147         t[x].sum:=1;
148         t[x].succ:=z;
149         t[x].pred:=z;
150         exit;
151     end;
152     with t[x] do mid:=(left+right) div 2;
153     if mid<l then change(x*2+1,l,r,z) else
154     if mid>=r then change(x*2,l,r,z) else
155     begin
156         change(x*2,l,mid,z);
157         change(x*2+1,mid+1,r,z);
158     end;
159     t[x].succ:=t[x*2].succ;
160     t[x].pred:=t[x*2+1].pred;
161     if t[x*2].pred=t[x*2+1].succ then
162         t[x].sum:=t[x*2].sum+t[x*2+1].sum-1 else
163         t[x].sum:=t[x*2].sum+t[x*2+1].sum;
164 end;
165
167 var
168     mid                                 :longint;
169 t1, t2     :rec;
170 begin
171     if t[x].lazy<>0 then
172     begin
173         t[x*2].lazy:=t[x].lazy;
174         t[x*2].sum:=1;
175         t[x*2].succ:=t[x].lazy;
176         t[x*2].pred:=t[x].lazy;
177         t[x*2+1].lazy:=t[x].lazy;
178         t[x*2+1].sum:=1;
179         t[x*2+1].succ:=t[x].lazy;
180         t[x*2+1].pred:=t[x].lazy;
181         t[x].lazy:=0;
182     end;
183
184     if (t[x].left=l) and (t[x].right=r) then
185     begin
189         exit;
190     end;
191
192     with t[x] do mid:=(left+right) div 2;
193     if mid<l then
194     begin
199     end else
200     if mid>=r then
201     begin
206     end else
207     begin
212         if t1.pred=t2.succ then
215     end;
216 end;
217
218 procedure paint(x,y,z:longint);
219 begin
220     if dep[x]>dep[y] then swap(x,y);
221     while dep[x]<dep[y] do
222     begin
223         change(1,num[top[y]],num[y],z);
224         y:=father[top[y]];
225     end;
226     while top[x]<>top[y] do
227     begin
228         change(1,num[top[x]],num[x],z);
229         change(1,num[top[y]],num[y],z);
230         x:=father[top[x]];
231         y:=father[top[y]];
232     end;
233     x:=num[x];
234     y:=num[y];
235     if x>y then swap(x,y);
236     change(1,x,y,z);
237 end;
238
239 procedure query(x,y:longint);
240 var
241     ans                                 :longint;
242     a, b                                :longint;
243 begin
244     ans:=0;
245     if dep[x]>dep[y] then swap(x,y);
246     while dep[x]<dep[y] do
247     begin
251         if a=b then dec(ans);
252         y:=father[top[y]];
253     end;
254     while top[x]<>top[y] do
255     begin
259         if a=b then dec(ans);
263         if a=b then dec(ans);
264         x:=father[top[x]];
265         y:=father[top[y]];
266     end;
267     x:=num[x];
268     y:=num[y];
269     if x>y then swap(x,y);
271     writeln(ans);
272 end;
273
274 procedure main;
275 var
276     i                                   :longint;
277     c                                   :char;
278     x, y, z                             :longint;
279
280 begin
282     for i:=1 to m do
283     begin
285         if c='Q' then
286         begin
288             query(x,y)
289         end else
290         begin
300 end.