1 program bzoj1984;
2 const maxn=100010;maxm=200010;
3 var n,i,j,x,y,z,cnt,t:longint;
4 ch:char;
5 ter,next,w:array[-1..maxm]of longint;
6 link,deep,size,v,son,pos,belong:array[-1..maxn]of longint;
7 tr:array[-1..5*maxn]of record l,r,mx,add,c:longint;wait:boolean;end;
8 fa:array[-1..maxn,-1..20]of longint;
9
10 function max(a,b:longint):longint;
11 begin
12 if a>b then exit(a) else exit(b);
13 end;
14
15 procedure add(x,y,z:longint);
16 begin
17 inc(j);ter[j]:=y;next[j]:=link[x];link[x]:=j;w[j]:=z;
18 inc(j);ter[j]:=x;next[j]:=link[y];link[y]:=j;w[j]:=z;
19 end;
20
21 procedure dfs1(p:longint);
22 var i,j:longint;
23 begin
24 size[p]:=1;
25 for i:=1 to 17 do
26 begin
27 if deep[p]<=1 << i then break;
28 fa[p][i]:=fa[fa[p][i-1]][i-1];
29 end;
30 j:=link[p];
31 while j<>0 do
32 begin
33 if deep[ter[j]]=0 then
34 begin
35 deep[ter[j]]:=deep[p]+1;
36 fa[ter[j]][0]:=p;
37 v[ter[j]]:=w[j];son[(j+1) >> 1]:=ter[j];
38 dfs1(ter[j]);
39 inc(size[p],size[ter[j]]);
40 end;
41 j:=next[j];
42 end;
43 end;
44
45 procedure dfs2(p,chain:longint);
46 var j,k:longint;
47 begin
48 inc(cnt);pos[p]:=cnt;belong[p]:=chain;
49 k:=0;
50 j:=link[p];
51 while j<>0 do
52 begin
53 if deep[ter[j]]>deep[p] then
54 if size[ter[j]]>size[k] then k:=ter[j];
55 j:=next[j];
56 end;
57 if k=0 then exit;
58 dfs2(k,chain);
59 j:=link[p];
60 while j<>0 do
61 begin
62 if deep[ter[j]]>deep[p] then
63 if k<>ter[j] then dfs2(ter[j],ter[j]);
64 j:=next[j];
65 end;
66 end;
67
68 procedure build(p,l,r:longint);
69 var mid:longint;
70 begin
71 tr[p].l:=l;tr[p].r:=r;tr[p].mx:=0;tr[p].wait:=false;tr[p].add:=0;
72 if l=r then exit;
73 mid:=(l+r) >> 1;
74 build(p << 1,l,mid);
75 build(p << 1+1,mid+1,r);
76 end;
77
78 procedure push(p:longint);
79 begin
80 if tr[p].l=tr[p].r then exit;
81 if tr[p].wait then
82 begin
83 //与上一题不同,这一题并不存在下面的点在更新之后能比现在更好的情况所以不需要push(p << 1);push(p << 1+1)
84 //否则会TLE
85 tr[p << 1].add:=0;tr[p << 1+1].add:=0;
86 //这两句很关键 因为当儿子节点再往下更新的时候如果add没有清零再往下的点会被赋上不等于tr[p].mx的值
87 tr[p << 1].mx:=tr[p].mx;tr[p << 1].wait:=true;
88 tr[p << 1+1].mx:=tr[p].mx;tr[p << 1+1].wait:=true;
89 tr[p].wait:=false;
90 tr[p].mx:=max(tr[p << 1].mx,tr[p << 1+1].mx);
91 end;
92 if tr[p].add<>0 then
93 begin
94 inc(tr[p << 1].mx,tr[p].add);
95 if not tr[p << 1].wait then inc(tr[p << 1].add,tr[p].add);
96 //这个特判很关键也很隐蔽 因为如果tr[p << 1].wait=True的话它往下传的时候应该把tr[p << 1].mx+tr[p].add传递下去
97 //但是如果把tr[p << 1].add也加上了tr[p].add的话相当于重复相加 就出错了
98 inc(tr[p << 1+1].mx,tr[p].add);
99 if not tr[p << 1+1].wait then inc(tr[p << 1+1].add,tr[p].add);
100 tr[p].add:=0;
101 tr[p].mx:=max(tr[p << 1].mx,tr[p << 1+1].mx);
102 end;
103 end;
104
105 procedure insert(p,l,r,ave:longint);
106 var mid:longint;
107 begin
108 push(p);
109 if (tr[p].l=l)and(tr[p].r=r) then
110 begin
111 tr[p].mx:=ave;tr[p].wait:=true;
112 exit;
113 end;
114 mid:=(tr[p].l+tr[p].r) >> 1;
115 if r<=mid then insert(p << 1,l,r,ave) else
116 if l>mid then insert(p << 1+1,l,r,ave) else
117 begin
118 insert(p << 1,l,mid,ave);
119 insert(p << 1+1,mid+1,r,ave);
120 end;
121 tr[p].mx:=max(tr[p << 1].mx,tr[p << 1+1].mx);
122 end;
123
124 function lca(x,y:longint):longint;
125 var tem,i:longint;
126 begin
127 if deep[x]<deep[y] then
128 begin
129 tem:=x;x:=y;y:=tem;
130 end;
131 if deep[x]<>deep[y] then
132 begin
133 i:=trunc(ln(deep[x]-deep[y])/ln(2));
134 while deep[x]>deep[y] do
135 begin
136 while (deep[x]-deep[y]>=1 << i) do x:=fa[x][i];
137 dec(i);
138 end;
139 end;
140 if x=y then exit(x);
141 i:=trunc(ln(n)/ln(2));
142 while fa[x][0]<>fa[y,0] do
143 begin
144 while fa[x,i]<>fa[y,i] do
145 begin
146 x:=fa[x,i];y:=fa[y,i];
147 end;
148 dec(i);
149 end;
150 exit(fa[x,0]);
151 end;
152
153 procedure add(p,l,r,ave:longint);
154 var mid:longint;
155 begin
156 push(p);
157 if (tr[p].l=l)and(tr[p].r=r) then
158 begin
159 inc(tr[p].mx,ave);
160 inc(tr[p].add,ave);
161 exit;
162 end;
163 mid:=(tr[p].l+tr[p].r) >> 1;
164 if r<=mid then add(p << 1,l,r,ave) else
165 if l>mid then add(p << 1+1,l,r,ave) else
166 begin
167 add(p << 1,l,mid,ave);
168 add(p << 1+1,mid+1,r,ave);
169 end;
170 tr[p].mx:=max(tr[p << 1].mx,tr[p << 1+1].mx);
171 end;
172
173 function query(p,l,r:longint):longint;
174 var mid:longint;
175 begin
176 push(p);
177 if (tr[p].l=l)and(tr[p].r=r) then exit(tr[p].mx);
178 mid:=(tr[p].l+tr[p].r) >> 1;
179 if r<=mid then exit(query(p << 1,l,r)) else
180 if l>mid then exit(query(p << 1+1,l,r)) else
181 exit(max(query(p << 1,l,mid),query(p << 1+1,mid+1,r)));
182 end;
183
184 procedure solve_change(x,y,z:longint);
185 begin
186 while belong[x]<>belong[y] do
187 begin
188 insert(1,pos[belong[x]],pos[x],z);
189 x:=fa[belong[x]][0];
190 end;
191 if x<>y then insert(1,pos[y]+1,pos[x],z);
192 end;
193
194 procedure solve_add(x,y,z:longint);
195 begin
196 while belong[x]<>belong[y] do
197 begin
198 add(1,pos[belong[x]],pos[x],z);
199 x:=fa[belong[x]][0];
200 end;
201 if x<>y then add(1,pos[y]+1,pos[x],z);
202 end;
203
204 function solve_mx(x,y:longint):longint;
205 var sum:longint;
206 begin
207 sum:=0;
208 while belong[x]<>belong[y] do
209 begin
210 sum:=max(sum,query(1,pos[belong[x]],pos[x]));
211 x:=fa[belong[x]][0];
212 end;
213 if x<>y then sum:=max(sum,query(1,pos[y]+1,pos[x]));
214 exit(sum);
215 end;
216
217 begin
218 readln(n);
219 j:=0;
220 for i:=1 to n-1 do
221 begin
222 readln(x,y,z);
223 add(x,y,z);
224 end;
225 deep[1]:=1;dfs1(1);
226 cnt:=0;dfs2(1,1);
227 build(1,1,n);
228 for i:=1 to n do insert(1,pos[i],pos[i],v[i]);
229 read(ch);
230 while ch<>‘S‘ do
231 begin
232 if ch=‘C‘ then
233 begin
234 read(ch);
235 if ch=‘h‘ then
236 begin
237 readln(ch,ch,ch,ch,x,y);
238 insert(1,pos[son[x]],pos[son[x]],y);
239 end else
240 begin
241 readln(ch,ch,ch,x,y,z);
242 t:=lca(x,y);
243 solve_change(x,t,z);solve_change(y,t,z);
244 end;
245 end else
246 if ch=‘A‘ then
247 begin
248 readln(ch,ch,x,y,z);
249 t:=lca(x,y);
250 solve_add(x,t,z);solve_add(y,t,z);
251 end else
252 begin
253 readln(ch,ch,x,y);
254 t:=lca(x,y);
255 writeln(max(solve_mx(x,t),solve_mx(y,t)));
256 end;
257 read(ch);
258 end;
259 end.
260