不难想到树链剖分
这题的难点是记录的是路径上宗教相同的点
裸的想法是对每一种宗教都开一棵线段树,记录每个点的评级
但显然这样会爆空间,仔细分析一下,这些线段树内很多点压根就没用到
因此我们考虑对线段树动态开点,不难发现每次修改最多要开线段树上O(2*logn)个点,是可以接受的
然后就是打码的问题了
1 type node=record 2 po,next:longint; 3 end; 4 link=record 5 l,r,s,m:longint; 6 end; 7 8 var tree:array[0..200010*20] of link; 9 fa,size,d,top,p,c,h,b,w:array[0..100010] of longint; 10 e:array[0..200010] of node; 11 len,t,i,n,q,x,y:longint; 12 ch:char; 13 14 function max(a,b:longint):longint; 15 begin 16 if a>b then exit(a) else exit(b); 17 end; 18 19 procedure swap(var a,b:longint); 20 var c:longint; 21 begin 22 c:=a; 23 a:=b; 24 b:=c; 25 end; 26 27 procedure add(x,y:longint); 28 begin 29 inc(len); 30 e[len].po:=y; 31 e[len].next:=p[x]; 32 p[x]:=len; 33 end; 34 35 procedure update(x:longint); 36 begin 37 tree[x].s:=tree[tree[x].l].s+tree[tree[x].r].s; 38 tree[x].m:=max(tree[tree[x].l].m,tree[tree[x].r].m); 39 end; 40 41 procedure dfs1(x:longint); 42 var i,y:longint; 43 begin 44 size[x]:=1; 45 i:=p[x]; 46 while i<>0 do 47 begin 48 y:=e[i].po; 49 if fa[x]<>y then 50 begin 51 d[y]:=d[x]+1; 52 fa[y]:=x; 53 dfs1(y); 54 size[x]:=size[x]+size[y]; 55 end; 56 i:=e[i].next; 57 end; 58 end; 59 60 procedure dfs2(x:longint); 61 var i,y,q:longint; 62 begin 63 q:=0; 64 inc(t); 65 c[x]:=t; 66 i:=p[x]; 67 while i<>0 do 68 begin 69 y:=e[i].po; 70 if (c[y]=0) and (size[y]>size[q]) then q:=y; 71 i:=e[i].next; 72 end; 73 if q<>0 then 74 begin 75 top[q]:=top[x]; 76 dfs2(q); 77 end; 78 i:=p[x]; 79 while i<>0 do 80 begin 81 y:=e[i].po; 82 if c[y]=0 then 83 begin 84 top[y]:=y; 85 dfs2(y); 86 end; 87 i:=e[i].next; 88 end; 89 end; 90 91 function change(last,l,r,x,y:longint):longint; 92 var m,q:longint; 93 begin 94 inc(t); 95 if l=r then 96 begin 97 tree[t].m:=y; 98 tree[t].s:=y; 99 exit(t); 100 end 101 else begin 102 m:=(l+r) shr 1; 103 q:=t; 104 if x<=m then 105 begin 106 tree[q].r:=tree[last].r; 107 last:=tree[last].l; 108 tree[q].l:=change(last,l,m,x,y); 109 end 110 else begin 111 tree[q].l:=tree[last].l; 112 last:=tree[last].r; 113 tree[q].r:=change(last,m+1,r,x,y); 114 end; 115 update(q); 116 exit(q); 117 end; 118 end; 119 120 function getmax(now,l,r,x,y:longint):longint; 121 var m,q:longint; 122 begin 123 if (x<=l) and (y>=r) then exit(tree[now].m) 124 else begin 125 m:=(l+r) shr 1; 126 q:=0; 127 if (x<=m) and (tree[now].l<>0) then q:=getmax(tree[now].l,l,m,x,y); 128 if (y>m) and (tree[now].r<>0) then q:=max(q,getmax(tree[now].r,m+1,r,x,y)); 129 exit(q); 130 end; 131 end; 132 133 function getsum(now,l,r,x,y:longint):longint; 134 var m,q:longint; 135 begin 136 if (x<=l) and (y>=r) then exit(tree[now].s) 137 else begin 138 m:=(l+r) shr 1; 139 q:=0; 140 if (x<=m) and (tree[now].l<>0) then q:=q+getsum(tree[now].l,l,m,x,y); 141 if (y>m) and (tree[now].r<>0) then q:=q+getsum(tree[now].r,m+1,r,x,y); 142 exit(q); 143 end; 144 end; 145 146 function maxx(x,y:longint):longint; 147 var f1,f2,re:longint; 148 begin 149 maxx:=0; 150 re:=b[x]; 151 f1:=top[x]; 152 f2:=top[y]; 153 while f1<>f2 do 154 begin 155 if d[f1]>=d[f2] then 156 begin 157 maxx:=max(maxx,getmax(h[re],1,n,c[f1],c[x])); 158 x:=fa[f1]; 159 end 160 else begin 161 maxx:=max(maxx,getmax(h[re],1,n,c[f2],c[y])); 162 y:=fa[f2]; 163 end; 164 f1:=top[x]; 165 f2:=top[y]; 166 end; 167 if c[x]>c[y] then swap(x,y); 168 maxx:=max(maxx,getmax(h[re],1,n,c[x],c[y])); 169 end; 170 171 function ask(x,y:longint):longint; 172 var f1,f2,re:longint; 173 begin 174 ask:=0; 175 re:=b[x]; 176 f1:=top[x]; 177 f2:=top[y]; 178 while f1<>f2 do 179 begin 180 if d[f1]>=d[f2] then 181 begin 182 ask:=ask+getsum(h[re],1,n,c[f1],c[x]); 183 x:=fa[f1]; 184 end 185 else begin 186 ask:=ask+getsum(h[re],1,n,c[f2],c[y]); 187 y:=fa[f2]; 188 end; 189 f1:=top[x]; 190 f2:=top[y]; 191 end; 192 if c[x]>c[y] then swap(x,y); 193 ask:=ask+getsum(h[re],1,n,c[x],c[y]); 194 end; 195 196 begin 197 readln(n,q); 198 for i:=1 to n do 199 readln(w[i],b[i]); 200 for i:=1 to n-1 do 201 begin 202 readln(x,y); 203 add(x,y); 204 add(y,x); 205 end; 206 d[1]:=1; 207 dfs1(1); 208 top[1]:=1; 209 dfs2(1); 210 t:=0; 211 for i:=1 to n do 212 h[b[i]]:=change(h[b[i]],1,n,c[i],w[i]); 213 for i:=1 to q do 214 begin 215 read(ch); 216 if ch='C' then 217 begin 218 readln(ch,x,y); 219 if ch='C' then 220 begin 221 h[b[x]]:=change(h[b[x]],1,n,c[x],0); 222 b[x]:=y; 223 h[y]:=change(h[y],1,n,c[x],w[x]); 224 end 225 else begin 226 w[x]:=y; 227 h[b[x]]:=change(h[b[x]],1,n,c[x],y); 228 end; 229 end 230 else begin 231 readln(ch,x,y); 232 if ch='M' then 233 writeln(maxx(x,y)) 234 else writeln(ask(x,y)); 235 end; 236 end; 237 end.