很明显是树链剖分吧
然后很明显要用线段树维护吧,即维护一段区间首、尾颜色和区间内颜色总数
然后修改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.