首页 > 代码库 > BZOJ3531: [Sdoi2014]旅行
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
Round 1 Day 1
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 begin101 if k=0 then exit(0);102 with t[k] do103 begin104 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 begin112 if k=0 then exit(0);113 with t[k] do114 begin115 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 begin123 ans:=0;124 readln(x,y);root:=rt[c[x]];125 while top[x]<>top[y] do126 begin127 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 begin137 ans:=0;138 readln(x,y);root:=rt[c[x]];139 while top[x]<>top[y] do140 begin141 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 begin151 for i:=1 to m do152 begin153 read(ch,ch);154 case ch of155 ‘W‘:begin156 readln(x,y);157 w[x]:=y;158 change(rt[c[x]],1,n,p[x],y);159 end;160 ‘C‘:begin161 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 begin172 assign(input,‘input.txt‘);assign(output,‘output.txt‘);173 reset(input);rewrite(output);174 init;175 main;176 close(input);close(output);177 end.