BZOJ3531: [Sdoi2014]旅行
3531: [Sdoi2014]旅行
Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 333 Solved: 197
[Submit][Status]
Description
S国有N个城市,编号从1到N。城市间用N-1条双向道路连接,满足
从一个城市出发可以到达其它所有城市。每个城市信仰不同的宗教,如飞天面条神教、隐形独角兽教、绝地教都是常见的信仰。为了方便,我们用不同的正整数代表各种宗教, S国的居民常常旅行。旅行时他们总会走最短路,并且为了避免麻烦,只在信仰和他们相同的城市留宿。当然旅程的终点也是信仰与他相同的城市。S国政府为每个城市标定了不同的旅行评级,旅行者们常会记下途中(包括起点和终点)留宿过的城市的评级总和或最大值。
在S国的历史上常会发生以下几种事件:
”CC x c”:城市x的居民全体改信了c教;
”CW x w”:城市x的评级调整为w;
”QS x y”:一位旅行者从城市x出发,到城市y,并记下了途中留宿过的城市的评级总和;
”QM x y”:一位旅行者从城市x出发,到城市y,并记下了途中留宿过
的城市的评级最大值。
由于年代久远,旅行者记下的数字已经遗失了,但记录开始之前每座城市的信仰与评级,还有事件记录本身是完好的。请根据这些信息,还原旅行者记下的数字。 为了方便,我们认为事件之间的间隔足够长,以致在任意一次旅行中,所有城市的评级和信仰保持不变。
Input
输入的第一行包含整数N,Q依次表示城市数和事件数。
接下来N行,第i+l行两个整数Wi,Ci依次表示记录开始之前,城市i的
评级和信仰。
接下来N-1行每行两个整数x,y表示一条双向道路。
接下来Q行,每行一个操作,格式如上所述。
Output
对每个QS和QM事件,输出一行,表示旅行者记下的数字。
Sample Input
3 1
2 3
1 2
3 3
5 1
1 2
1 3
3 4
3 5
QS 1 5
CC 3 1
QS 1 5
CW 3 3
QS 1 5
QM 2 4
Sample Output
9
11
3
HINT
N,Q < =10^5 , C < =10^5
数据保证对所有QS和QM事件,起点和终点城市的信仰相同;在任意时
刻,城市的评级总是不大于10^4的正整数,且宗教值不大于C。
Source
1 {$M 10000000,0,maxlongint} 2 const maxn=100000+10; 3 type node1=record 4 go,next:longint; 5 end; 6 node2=record 7 l,r,mid,lch,rch,mx:longint; 8 sum:int64; 9 end; 10 11 var e:array[0..2*maxn] of node1; 12 t:array[0..40*maxn] of node2; 13 p,fa,s,head,dep,son,top,w,c,rt:array[0..maxn] of longint; 14 i,n,m,x,y,z,sz,tot,cnt,root:longint; 15 ans:int64; 16 ch:char; 17 procedure swap(var x,y:longint); 18 var t:longint; 19 begin 20 t:=x;x:=y;y:=t; 21 end; 22 procedure insert(x,y:longint); 23 begin 24 inc(tot); 25 e[tot].go:=y;e[tot].next:=head[x];head[x]:=tot; 26 end; 27 function min(x,y:longint):longint; 28 begin 29 if x<y then exit(x) else exit(y); 30 end; 31 function max(x,y:longint):longint; 32 begin 33 if x>y then exit(x) else exit(y); 34 end; 35 procedure dfs1(x:longint); 36 var i,j,y:longint; 37 begin 38 j:=0;s[x]:=1; 39 i:=head[x]; 40 while i<>0 do 41 begin 42 y:=e[i].go; 43 if dep[y]=0 then 44 begin 45 dep[y]:=dep[x]+1; 46 fa[y]:=x; 47 dfs1(y); 48 inc(s[x],s[y]); 49 if s[y]>s[j] then j:=y; 50 end; 51 i:=e[i].next; 52 end; 53 son[x]:=j; 54 end; 55 procedure dfs2(x,chain:longint); 56 var i,y:longint; 57 begin 58 inc(sz);p[x]:=sz;top[x]:=chain; 59 if son[x]<>0 then dfs2(son[x],chain); 60 i:=head[x]; 61 while i<>0 do 62 begin 63 y:=e[i].go; 64 if (y<>son[x]) and (y<>fa[x]) then dfs2(y,y); 65 i:=e[i].next; 66 end; 67 end; 68 procedure pushup(k:longint); 69 begin 70 with t[k] do 71 begin 72 mx:=max(t[lch].mx,t[rch].mx); 73 sum:=t[lch].sum+t[rch].sum; 74 end; 75 end; 76 procedure change(var k:longint;x,y,pos,val:longint); 77 begin 78 if k=0 then begin inc(cnt);k:=cnt;end; 79 with t[k] do 80 begin 81 l:=x;r:=y;mid:=(l+r)>>1; 82 if l=r then begin mx:=val;sum:=val;exit;end; 83 if pos<=mid then change(lch,l,mid,pos,val) 84 else change(rch,mid+1,r,pos,val); 85 pushup(k); 86 end; 87 end; 88 procedure init; 89 begin 90 readln(n,m); 91 for i:=1 to n do readln(w[i],c[i]); 92 for i:=1 to n-1 do begin readln(x,y);insert(x,y);insert(y,x);end; 93 dep[1]:=1; 94 dfs1(1); 95 dfs2(1,1); 96 cnt:=0; 97 for i:=1 to n do change(rt[c[i]],1,n,p[i],w[i]); 98 end; 99 function getmx(k,x,y:longint):longint; 100 begin 101 if k=0 then exit(0); 102 with t[k] do 103 begin 104 if (l=x) and (r=y) then exit(mx); 105 if y<=mid then exit(getmx(lch,x,y)) 106 else if x>mid then exit(getmx(rch,x,y)) 107 else exit(max(getmx(lch,x,mid),getmx(rch,mid+1,y))); 108 end; 109 end; 110 function getsum(k,x,y:longint):int64; 111 begin 112 if k=0 then exit(0); 113 with t[k] do 114 begin 115 if (l=x) and (r=y) then exit(sum); 116 if y<=mid then exit(getsum(lch,x,y)) 117 else if x>mid then exit(getsum(rch,x,y)) 118 else exit(getsum(lch,x,mid)+getsum(rch,mid+1,y)); 119 end; 120 end; 121 procedure solvemx; 122 begin 123 ans:=0; 124 readln(x,y);root:=rt[c[x]]; 125 while top[x]<>top[y] do 126 begin 127 if dep[top[x]]<dep[top[y]] then swap(x,y); 128 ans:=max(ans,getmx(root,p[top[x]],p[x])); 129 x:=fa[top[x]]; 130 end; 131 if dep[x]>dep[y] then swap(x,y); 132 ans:=max(ans,getmx(root,p[x],p[y])); 133 writeln(ans); 134 end; 135 procedure solvesum; 136 begin 137 ans:=0; 138 readln(x,y);root:=rt[c[x]]; 139 while top[x]<>top[y] do 140 begin 141 if dep[top[x]]<dep[top[y]] then swap(x,y); 142 inc(ans,getsum(root,p[top[x]],p[x])); 143 x:=fa[top[x]]; 144 end; 145 if dep[x]>dep[y] then swap(x,y); 146 inc(ans,getsum(root,p[x],p[y])); 147 writeln(ans); 148 end; 149 procedure main; 150 begin 151 for i:=1 to m do 152 begin 153 read(ch,ch); 154 case ch of 155 'W':begin 156 readln(x,y); 157 w[x]:=y; 158 change(rt[c[x]],1,n,p[x],y); 159 end; 160 'C':begin 161 readln(x,y); 162 change(rt[c[x]],1,n,p[x],0); 163 c[x]:=y; 164 change(rt[y],1,n,p[x],w[x]); 165 end; 166 'M':solvemx; 167 'S':solvesum; 168 end; 169 end; 170 end; 171 begin 172 assign(input,'input.txt');assign(output,'output.txt'); 173 reset(input);rewrite(output); 174 init; 175 main; 176 close(input);close(output); 177 end.