不难想到树链剖分
这题的难点是记录的是路径上宗教相同的点
裸的想法是对每一种宗教都开一棵线段树,记录每个点的评级
但显然这样会爆空间,仔细分析一下,这些线段树内很多点压根就没用到
因此我们考虑对线段树动态开点,不难发现每次修改最多要开线段树上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.
View Code

 

posted on 2014-12-25 21:11  acphile  阅读(124)  评论(0编辑  收藏  举报