rt
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ft first
#define sd second
#define PII pair<int,int>
#define fst ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
inline int read() {
int x = 0, w = 1;
char ch = 0;
while (ch < '0' || ch > '9') {
if (ch == '-') w = -1;
ch = getchar(); }
while (ch >= '0' && ch <= '9') {
x = x * 10 + (ch - '0');
ch = getchar(); }
return x * w;
}
void write(int x) {
static int sta[35];
int top = 0;
do {
sta[top++] = x % 10, x /= 10;
} while (x);
while (top) putchar(sta[--top] + 48);
}
const int INF=0x3f3f3f3f,MOD=1e9+7;
const int N=2e5+5;
int n;
struct edge
{
int v,w,id;
};
int a[N];
int b[N];
vector<edge> g[N];
int tot;
int fa[N];
int sz[N];
int dfn[N];
int rnk[N];
int son[N];
int top[N];
int dep[N];
void dfs1(int x)
{
sz[x]=1;
son[x]=-1;
for(auto e: g[x])
{
int v=e.v;
int w=e.w;
if(fa[x]==v) continue;
a[v]=w;
b[e.id]=v;
fa[v]=x;
dep[v]=dep[x]+1;
dfs1(v);
sz[x]+=sz[v];
if(son[x]==-1||sz[v]>sz[son[x]]) son[x]=v;
}
}
void dfs2(int x,int t)
{
top[x]=t;
dfn[x]=++tot;
rnk[tot]=x;
if(son[x]!=-1) dfs2(son[x],t);
for(auto e: g[x])
{
int v=e.v;
if(v==fa[x]||v==son[x]) continue;
dfs2(v,v);
}
}
#define lson (rt<<1)
#define rson (rt<<1|1)
#define mid ((l+r)>>1)
struct Node
{
int l,r,v=0,miv=INF,mxv=-INF;
int lazy;
};
struct seg_tree
{
Node tr[N<<2];
void pushup(int rt)
{
tr[rt].v=tr[lson].v+tr[rson].v;
tr[rt].miv=min(tr[lson].miv,tr[rson].miv);
tr[rt].mxv=max(tr[lson].mxv,tr[rson].mxv);
}
void pushdown(int rt)
{
if(tr[rt].lazy)
{
tr[lson].v=-tr[lson].v;
swap(tr[lson].mxv,tr[lson].miv);
tr[lson].mxv=-tr[lson].mxv;
tr[lson].miv=-tr[lson].miv;
tr[lson].lazy^=1;
tr[rson].v=-tr[rson].v;
swap(tr[rson].mxv,tr[rson].miv);
tr[rson].mxv=-tr[rson].mxv;
tr[rson].miv=-tr[rson].miv;
tr[rson].lazy^=1;
tr[rt].lazy=0;
}
}
void build(int rt,int l,int r)
{
tr[rt]={l,r,0,INF,-INF,0};
if(l==r)
{
tr[rt].v=tr[rt].miv=tr[rt].mxv=a[rnk[l]];
return ;
}
build(lson,l,mid);
build(rson,mid+1,r);
pushup(rt);
}
void update(int rt,int st,int ed)
{
int l=tr[rt].l,r=tr[rt].r;
if(st<=l&&r<=ed)
{
tr[rt].v=-tr[rt].v;
swap(tr[rt].mxv,tr[rt].miv);
tr[rt].mxv=-tr[rt].mxv;
tr[rt].miv=-tr[rt].miv;
tr[rt].lazy^=1;
return ;
}
pushdown(rt);
if(st<=mid) update(lson,st,ed);
if(mid<ed) update(rson,st,ed);
pushup(rt);
}
Node query(int rt,int st,int ed)
{
int l=tr[rt].l;
int r=tr[rt].r;
if(st<=l&&r<=ed)
{
return tr[rt];
}
pushdown(rt);
if(ed<=mid)
return query(lson,st,ed);
if(mid<st)
return query(rson,st,ed);
Node L=query(lson,st,ed),R=query(rson,st,ed);
Node res;
res.v=L.v+R.v;
res.mxv=max(L.mxv,R.mxv);
res.miv=min(L.miv,R.miv);
res.l=L.l;
res.r=R.r;
return res;
}
void print(int rt)
{
int l=tr[rt].l;
int r=tr[rt].r;
cout<<"root: "<<rt<<" ["<<tr[rt].l<<" , "<<tr[rt].r<<" ] "<<" min: "<<tr[rt].miv<<" max: "<<tr[rt].mxv<<" value: "<<tr[rt].v<<endl;
if(l==r)
{
return ;
}
print(lson);
print(rson);
}
void update1(int rt,int x,int k)
{
int l=tr[rt].l;
int r=tr[rt].r;
if(l==r&&l==x)
{
tr[rt].v=tr[rt].miv=tr[rt].mxv=k;
return ;
}
pushdown(rt);
if(x<=mid) update1(lson,x,k);
if(mid<x) update1(rson,x,k);
pushup(rt);
}
}seg_tree;
#undef lson
#undef rson
#undef mid
void update_Path(int x,int y)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
seg_tree.update(1,dfn[top[x]],dfn[x]);
x=fa[top[x]];
}
if(dep[x]<dep[y]) swap(x,y);
seg_tree.update(1,dfn[y],dfn[x]);
}
Node query_Path(int x,int y)
{
Node res;
while(top[x]!=top[y])
{
// cout<<x<<' '<<y<<endl;
if(dep[top[x]]<dep[top[y]]) swap(x,y);
Node t=seg_tree.query(1,dfn[top[x]],dfn[x]);
res.v+=t.v;
res.miv=min(res.miv,t.miv);
res.mxv=max(res.mxv,t.mxv);
x=fa[top[x]];
}
if(dep[x]<dep[y]) swap(x,y);
Node t=seg_tree.query(1,dfn[y],dfn[x]);
res.v+=t.v;
res.miv=min(res.miv,t.miv);
res.mxv=max(res.mxv,t.mxv);
// cout<<t.v<<" "<<t.miv<<" "<<t.mxv<<endl;
return res;
}
int m;
signed main()
{
fst;
// freopen("P1505_1.in","r",stdin);
// freopen("P1505_1.ans","w",stdout);
cin>>n;
for(int i=1;i<n;i++)
{
int u,v,w;
cin>>u>>v>>w;
g[u].push_back({v,w,i});
g[v].push_back({u,w,i});
}
// for(int i=0;i<n;i++)
// {
// for(auto e: g[i])
// {
// cout<<e.v<<" ";
// }
// cout<<endl;
// }
dfs1(0);
dfs2(0,0);
seg_tree.build(1,1,tot);
// seg_tree.print(1);
cin>>m;
while(m--)
{
string op;
cin>>op;
if(op[0]=='C')
{
int x,w;
cin>>x>>w;
seg_tree.update1(1,dfn[b[x]],w);
}
else if(op[0]=='N')
{
int l,r;
cin>>l>>r;
update_Path(l,r);
}
else if(op[0]=='S')
{
int u,v;
cin>>u>>v;
cout<<query_Path(u,v).v<<endl;
}
else if(op[1]=='A')
{
int u,v;
cin>>u>>v;;
cout<<query_Path(u,v).mxv<<endl;
}
else{
int u,v;
cin>>u>>v;
cout<<query_Path(u,v).miv<<endl;
}
}
return 0;
}
码风不好勿喷