bzoj2243

很明显是树链剖分吧
然后很明显要用线段树维护吧,即维护一段区间首、尾颜色和区间内颜色总数
然后修改lazy tag弄一弄,查询注意这一段尾和下一段首的颜色可能相同
然后就没什么了

  1 type node=record
  2        po,next:longint;
  3      end;
  4      link=record
  5        l,r,s:longint;
  6      end;
  7 
  8 var tree:array[0..400010] of link;
  9     lazy:array[0..400010] of longint;
 10     w:array[0..200010] of node;
 11     top,fa,d,size,a,b,c,p:array[0..100010] of longint;
 12     cas,i,n,m,x,y,z,len,t,prf,plf,rf,lf:longint;
 13     ch:char;
 14 
 15 procedure swap(var a,b:longint);
 16   var c:longint;
 17   begin
 18     c:=a;
 19     a:=b;
 20     b:=c;
 21   end;
 22 
 23 procedure add(x,y:longint);
 24   begin
 25     inc(len);
 26     w[len].po:=y;
 27     w[len].next:=p[x];
 28     p[x]:=len;
 29   end;
 30 
 31 procedure dfs1(x:longint);
 32   var i,y:longint;
 33   begin
 34     size[x]:=1;
 35     i:=p[x];
 36     while i<>0 do
 37     begin
 38       y:=w[i].po;
 39       if fa[x]<>y then
 40       begin
 41         d[y]:=d[x]+1;
 42         fa[y]:=x;
 43         dfs1(y);
 44         size[x]:=size[x]+size[y];
 45       end;
 46       i:=w[i].next;
 47     end;
 48   end;
 49 
 50 procedure dfs2(x:longint);
 51   var q,i,y:longint;
 52   begin
 53     i:=p[x];
 54     q:=0;
 55     inc(t);
 56     c[x]:=t;
 57     b[t]:=x;
 58     while i<>0 do
 59     begin
 60       y:=w[i].po;
 61       if fa[x]<>y then
 62         if size[q]<size[y] then q:=y;
 63       i:=w[i].next;
 64     end;
 65     if q<>0 then
 66     begin
 67       top[q]:=top[x];
 68       dfs2(q);
 69     end;
 70     i:=p[x];
 71     while i<>0 do
 72     begin
 73       y:=w[i].po;
 74       if top[y]=0 then
 75       begin
 76         top[y]:=y;
 77         dfs2(y);
 78       end;
 79       i:=w[i].next;
 80     end;
 81   end;
 82 
 83 procedure update(i:longint);
 84   begin
 85     tree[i].l:=tree[i*2].l;
 86     tree[i].r:=tree[i*2+1].r;
 87     tree[i].s:=tree[i*2].s+tree[i*2+1].s;
 88     if tree[i*2].r=tree[i*2+1].l then dec(tree[i].s);
 89   end;
 90 
 91 procedure build(i,l,r:longint);
 92   var m:longint;
 93   begin
 94     if l=r then
 95     begin
 96       tree[i].l:=a[b[l]];
 97       tree[i].r:=a[b[l]];
 98       tree[i].s:=1;
 99     end
100     else begin
101       m:=(l+r) shr 1;
102       build(i*2,l,m);
103       build(i*2+1,m+1,r);
104       update(i);
105     end;
106   end;
107 
108 procedure push(i:longint);
109   begin
110     tree[i*2].l:=lazy[i];
111     tree[i*2+1].l:=lazy[i];
112     tree[i*2].r:=lazy[i];
113     tree[i*2+1].r:=lazy[i];
114     tree[i*2+1].s:=1;
115     tree[i*2].s:=1;
116     lazy[i*2]:=lazy[i];
117     lazy[i*2+1]:=lazy[i];
118     lazy[i]:=-1;
119   end;
120 
121 procedure change(i,l,r,x,y,z:longint);
122   var m:longint;
123   begin
124     if (x<=l) and (y>=r) then
125     begin
126       tree[i].l:=z;
127       tree[i].r:=z;
128       tree[i].s:=1;
129       lazy[i]:=z;
130     end
131     else begin
132       m:=(l+r) shr 1;
133       if lazy[i]<>-1 then push(i);
134       if x<=m then change(i*2,l,m,x,y,z);
135       if y>m then change(i*2+1,m+1,r,x,y,z);
136       update(i);
137     end;
138   end;
139 
140 procedure work(x,y,z:longint);
141   var f1,f2:longint;
142   begin
143     f1:=top[x];
144     f2:=top[y];
145     while f1<>f2 do
146     begin
147       if d[f1]>=d[f2] then
148       begin
149         change(1,1,n,c[f1],c[x],z);
150         x:=fa[f1];
151       end
152       else begin
153         change(1,1,n,c[f2],c[y],z);
154         y:=fa[f2];
155       end;
156       f1:=top[x];
157       f2:=top[y];
158     end;
159     if c[x]>c[y] then swap(x,y);
160     change(1,1,n,c[x],c[y],z);
161   end;
162 
163 function getans(i,l,r,x,y:longint):longint;
164   var m:longint;
165   begin
166     if (x<=l) and (y>=r) then getans:=tree[i].s
167     else begin
168       m:=(l+r) shr 1;
169       if lazy[i]<>-1 then push(i);
170       getans:=0;
171       if x<=m then getans:=getans+getans(i*2,l,m,x,y);
172       if y>m then getans:=getans+getans(i*2+1,m+1,r,x,y);
173       if (x<=m) and (y>m) and (tree[i*2].r=tree[i*2+1].l) then
174         getans:=getans-1;
175     end;
176     if l=x then
177     begin
178       if cas=1 then
179         lf:=tree[i].l
180       else rf:=tree[i].l;
181     end;
182     if r=y then t:=tree[i].r;
183   end;
184 
185 function ask(x,y:longint):longint;
186   var f1,f2,s:longint;
187   begin
188     f1:=top[x];
189     f2:=top[y];
190     s:=0;
191     prf:=-1;
192     plf:=-1;
193     lf:=-1;
194     rf:=-1;
195     while f1<>f2 do
196     begin
197       if d[f1]>=d[f2] then
198       begin
199         cas:=1;
200         s:=s+getans(1,1,n,c[f1],c[x]);
201         if t=plf then dec(s); //维护x链的尾部
202         plf:=lf;
203         x:=fa[f1];
204       end
205       else begin
206         cas:=2;
207         s:=s+getans(1,1,n,c[f2],c[y]);
208         if t=prf then dec(s);  //维护y链尾部
209         prf:=rf;
210         y:=fa[f2];
211       end;
212       f1:=top[x];
213       f2:=top[y];
214     end;
215 
216     if c[x]>c[y] then
217     begin
218       swap(x,y);
219       swap(prf,plf);
220     end;
221     cas:=1;
222     s:=s+getans(1,1,n,c[x],c[y]);
223     if lf=plf then dec(s); //注意这里有两种情况
224     if t=prf then dec(s);
225     exit(s);
226   end;
227 
228 begin
229   readln(n,m);
230   for i:=1 to n do
231     read(a[i]);
232   for i:=1 to n-1 do
233   begin
234     readln(x,y);
235     add(x,y);
236     add(y,x);
237   end;
238   d[1]:=1;
239   dfs1(1);
240   top[1]:=1;
241   dfs2(1);
242   build(1,1,n);
243   fillchar(lazy,sizeof(lazy),255);
244   for i:=1 to m do
245   begin
246     read(ch);
247     if ch='C' then
248     begin
249       readln(x,y,z);
250       work(x,y,z);
251     end
252     else begin
253       readln(x,y);
254       writeln(ask(x,y));
255     end;
256   end;
257 end.
View Code
原文地址:https://www.cnblogs.com/phile/p/4473089.html