1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4 #define N 20010
5 #define inc(i,j,k) for(int i=j;i<=k;i++)
6 #define INF 0x3fffffff
7 using namespace std;
8
9 //general
10 int n,m;
11 void debug(){
12 n=n;
13 }
14
15 //edge
16 struct e{int t,w,n;}; e es[N*2]; int ess,g[N];
17 void pe(int f,int t,int w){es[++ess]=(e){t,w,g[f]}; g[f]=ess; es[++ess]=(e){f,w,g[t]}; g[t]=ess;}
18
19 //splay
20 int fa[N]/*点的父亲,包括在splay中的父亲和所在splay的父亲*/,c[N][2]/*splay中的儿子节点*/;
21 int sm[N],mx[N],mn[N],v[N],/*区间维护信息*/dt[N],dts/*中间过程用*/; bool tg[N]/*标记*/;
22 inline bool is_root(int x){return fa[x]==0||(c[fa[x]][0]!=x&&c[fa[x]][1]!=x);}//判断是否为所在splay的根节点
23 void pushdown(int x){//标记下传。注:本程序中的标记表明本节点已更新子孙未更新
24 if(x==0)return;
25 if(tg[x]){
26 int l=c[x][0],r=c[x][1]; tg[x]^=1;
27 if(l){tg[l]^=1; v[l]=-v[l]; sm[l]=-sm[l]; int t=mx[l]; mx[l]=-mn[l]; mn[l]=-t;}
28 if(r){tg[r]^=1; v[r]=-v[r]; sm[r]=-sm[r]; int t=mx[r]; mx[r]=-mn[r]; mn[r]=-t;}
29 }
30 }
31 void update(int x){
32 if(x==0)return;
33 int l=c[x][0],r=c[x][1]; sm[x]=v[x]+sm[l]+sm[r]; mx[x]=max(v[x],max(mx[l],mx[r])); mn[x]=min(v[x],min(mn[l],mn[r]));
34 }
35 void rotate(int x){//旋转
36 if(x==0||is_root(x))return;
37 int a=fa[x],b=fa[fa[x]]; bool d=c[a][1]==x,e=c[b][1]==a;
38 if(! is_root(a))c[b][e]=x;//注意在调用is_root前不能动参数的fa[a]和c[fa[a]][0]c[fa[a]][1],不然会导致错误结果
39 if(c[x][!d])fa[c[x][!d]]=a;/*注意别漏*/ fa[x]=b; fa[a]=x; c[a][d]=c[x][!d]; c[x][!d]=a;//注意修改的相对顺序
40 update(a); update(x); if(! is_root(x))update(b);
41 }
42 void splay(int x){//伸展
43 if(x==0)return;
44 dts=0; int t=x;
45 while(! is_root(t))dt[++dts]=t,t=fa[t]; dt[++dts]=t;//将根结点到x的所有标记一次下传
46 while(dts)pushdown(dt[dts]),dts--;
47 while(! is_root(x)){
48 if(!is_root(fa[x])) (c[fa[x]][1]==x)^(c[fa[fa[x]]][1]==fa[x])?rotate(x):rotate(fa[x]);
49 rotate(x);
50 }
51 }
52
53 //lct
54 int access(int x){//lct基本操作,使节点到根节点连成一条链,并把链上的分支断开
55 if(x==0)return 0;
56 int t=0;
57 while(x){
58 splay(x); c[x][1]=t; if(t)fa[t]=x;
59 update(x); t=x; x=fa[x];
60 }
61 debug();
62 return t;
63 }
64 void link(int x,int y){//lct基本操作,本程序不用
65 if(x==0||y==0)return;
66 access(x); splay(x); fa[x]=y;
67 }
68 void cut(int x){//lct基本操作,本程序不用
69 if(x==0)return;
70 access(x); splay(x); if(c[x][0])fa[c[x][0]]=0; c[x][0]=0; update(x);
71 }
72
73 //command
74 //注意修改时要根据题目要求将修改查询边权变为程序中的修改查询点权
75 void change(int x,int val){//更新权值
76 splay(x); v[x]=val; update(x);
77 }
78 void rever(int x,int y){//反转
79 access(x); int a=access(y); /*别*/splay(x);/*漏!下同*/
80 if(x==a){
81 int r=c[x][1]; tg[r]^=1; v[r]=-v[r]; sm[r]=-sm[r]; int t=mx[r]; mx[r]=-mn[r]; mn[r]=-t; update(x);
82 }else{
83 tg[x]^=1; v[x]=-v[x]; sm[x]=-sm[x]; int t=mx[x]; mx[x]=-mn[x]; mn[x]=-t;
84 int r=c[a][1]; tg[r]^=1; v[r]=-v[r]; sm[r]=-sm[r]; t=mx[r]; mx[r]=-mn[r]; mn[r]=-t;
85 update(a);
86 }
87 }
88 int querysum(int x,int y){//求和
89 access(x); int a=access(y); splay(x);
90 if(x==a)return sm[c[x][1]];else return sm[x]+sm[c[a][1]];
91 }
92 int querymax(int x,int y){//求最大值
93 access(x); int a=access(y); splay(x);
94 if(x==a)return mx[c[x][1]];else return max(mx[x],mx[c[a][1]]);
95 }
96 int querymin(int x,int y){//求最小值
97 access(x); int a=access(y); splay(x);
98 if(x==a)return mn[c[x][1]];else return min(mn[x],mn[c[a][1]]);
99 }
100
101 int num[N];
102 void dfs(int x){//建树,并将边权转为点权 ,本程序用边的终点点权表示这条边的边权
103 for(int i=g[x];i!=-1;i=es[i].n)if(es[i].t!=fa[x]){
104 fa[es[i].t]=x; v[es[i].t]=sm[es[i].t]=mx[es[i].t]=mn[es[i].t]=es[i].w; dfs(es[i].t);
105 }
106 }
107 int main(){
108 //freopen("big.txt","r",stdin); freopen("big.out","w",stdout);
109 memset(num,0,sizeof(num)); ess=0; memset(g,-1,sizeof(g)); memset(fa,0,sizeof(fa));
110 scanf("%d",&n); inc(i,1,n-1){int a,b,c; scanf("%d%d%d",&a,&b,&c); pe(a+1,b+1,c); num[i]=b+1;}
111 dfs(1);
112 memset(c,0,sizeof(c)); memset(tg,0,sizeof(tg)); mn[0]=INF; mx[0]=-INF; scanf("%d",&m); char s[10];
113 inc(i,1,m){
114 int a,b; scanf("%s%d%d",s,&a,&b);
115 if(s[0]==‘C‘)change(num[a],b);
116 if(s[0]==‘N‘)a++,b++,rever(a,b);
117 if(s[0]==‘S‘)a++,b++,printf("%d\n",querysum(a,b));
118 if(s[1]==‘A‘)a++,b++,printf("%d\n",querymax(a,b));
119 if(s[1]==‘I‘)a++,b++,printf("%d\n",querymin(a,b));
120 }
121 return 0;
122 }