using namespace std; int n,step; int w[maxn]; int sz[maxn],dep[maxn],fa[maxn],son[maxn]; int id[maxn],top[maxn]; int val[maxn]; int fi[maxn],se[maxn]; struct node{ int to,w; node(int to,int w):to(to),w(w){} }; int Max[maxn<<2],Min[maxn<<2],lazy[maxn<<2]; vector<node>e[maxn]; void init(){ for(int i=0;i<=n;i++) e[i].clear(); mm(sz,0),mm(dep,0),mm(fa,0),mm(son,0); mm(id,0),mm(top,0),mm(val,0),mm(lazy,0); mm(Max,0),mm(Min,0),mm(fi,0),mm(se,0),mm(w,0); step=0; } void dfs1(int x,int f,int deep){ sz[x]=1,fa[x]=f,son[x]=0,dep[x]=deep; int len=e[x].size(); for(int i=0;i<len;i++){ int next=e[x][i].to; if(next==f) continue; w[next]=e[x][i].w; dfs1(next,x,deep+1); sz[x]+=sz[next]; if(sz[son[x]]<sz[next]) son[x]=next; } } void dfs2(int x,int tp){ top[x]=tp; id[x]=++step; val[id[x]]=x; if(son[x]) dfs2(son[x],tp); int len=e[x].size(); for(int i=0;i<len;i++){ int next=e[x][i].to; if(next==fa[x] || next==son[x]) continue; dfs2(next,next); } } void push_up(int rt){ Max[rt]=max(Max[rt<<1],Max[rt<<1|1]); Min[rt]=min(Min[rt<<1],Min[rt<<1|1]); } void push_down(int rt){ if(lazy[rt]){ lazy[rt<<1]^=1; lazy[rt<<1|1]^=1; swap(Max[rt<<1],Min[rt<<1]); Max[rt<<1]=-Max[rt<<1]; Min[rt<<1]=-Min[rt<<1]; swap(Max[rt<<1|1],Min[rt<<1|1]); Max[rt<<1|1]=-Max[rt<<1|1]; Min[rt<<1|1]=-Min[rt<<1|1]; lazy[rt]=0; } } void build(int rt,int l,int r){ if(l==r){ Max[rt]=Min[rt]=w[val[l]]; return; } int mid=(l+r)>>1; build(lson); build(rson); push_up(rt); } void change(int rt,int l,int r,int x,int k){ if(l==r){ Max[rt]=Min[rt]=k; return; } push_down(rt); int mid=(l+r)>>1; if(mid>=x) change(lson,x,k); else change(rson,x,k); push_up(rt); } void negat(int rt,int l,int r,int L,int R){ if(l>=L && r<=R){ swap(Max[rt],Min[rt]); Max[rt]=-Max[rt]; Min[rt]=-Min[rt]; lazy[rt]^=1; return; } push_down(rt); int mid=(l+r)>>1; if(mid>=R) negat(lson,L,R); else if(mid<L) negat(rson,L,R); else{ negat(lson,L,R); negat(rson,L,R); } push_up(rt); } int query(int rt,int l,int r,int L,int R){ if(l>=L && r<=R) return Max[rt]; push_down(rt); int mid=(l+r)>>1; if(mid>=R) return query(lson,L,R); else if(mid<L) return query(rson,L,R); else return max(query(lson,L,R),query(rson,L,R)); } int querymx(int x,int y){ if(x==y) return 0; int ans=-inf; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]) swap(x,y); ans=max(ans,query(1,1,n,id[top[x]],id[x])); x=fa[top[x]]; } if(x==y) return ans; if(dep[x]>dep[y]) swap(x,y); ans=max(ans,query(1,1,n,id[son[x]],id[y])); return ans; } void solvene(int x,int y){ while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]) swap(x,y); negat(1,1,n,id[top[x]],id[x]); x=fa[top[x]]; } if(x==y) return ; if(dep[x]>dep[y]) swap(x,y); negat(1,1,n,id[son[x]],id[y]); } char op[10]; int main(){ // freopen("input.txt","r",stdin); int t; scanf("%d",&t); while(t--){ scanf("%d",&n); init(); for(int i=1;i<n;i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); fi[i]=u,se[i]=v; e[u].push_back(node(v,w)); e[v].push_back(node(u,w)); } dfs1(1,0,1); dfs2(1,1); build(1,1,n); for(int i=1;i<n;i++) fi[i]=dep[fi[i]]>dep[se[i]]?fi[i]:se[i]; while(scanf("%s",op)!=EOF){ if(op[0]=='D') break; if(op[0]=='C'){ int x,y; scanf("%d%d",&x,&y); change(1,1,n,id[fi[x]],y); } else if(op[0]=='N'){ int x,y; scanf("%d%d",&x,&y); solvene(x,y); } else { int x,y; scanf("%d%d",&x,&y); printf("%d\n",querymx(x,y)); } } } return 0; }
|