CHANGE i v Change the weight of the ith edge to v
NEGATE a b Negate the weight of every edge on the path from a to b
QUERY a b Find the maximum weight of edges on the path from a to b
Input
The input contains multiple test cases. The first line of input contains an integer t (t ≤ 20), the number of test cases. Then follow the test cases.
Each test case is preceded by an empty line. The first nonempty line of its contains N (N ≤ 10,000). The next N − 1 lines each contains three integers a, b and c, describing an edge connecting nodes a and b with weight c. The edges are numbered in the order they appear in the input. Below them are the instructions, each sticking to the specification above. A lines with the word “DONE” ends the test case.
Output
For each “QUERY” instruction, output the result on a separate line.
Sample Input
1
3
1 2 1
2 3 2
QUERY 1 2
CHANGE 1 3
QUERY 1 2
DONE
Sample Output
1
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 10005
int g[maxn];
struct node{
int to,nxt,vl;
}ed[maxn<<1];
int head[maxn],cnt;
void addedge(int u,int v,int vl){
ed[cnt].to=v;
ed[cnt].vl=vl;
ed[cnt].nxt=head[u];
head[u]=cnt++;
}
int sz[maxn],top[maxn],son[maxn],fa[maxn],p[maxn],dep[maxn];
int pos;
void dfs1(int u,int f,int d){
dep[u]=d;
sz[u]=1;
fa[u]=f;
for(int i=head[u];~i;i=ed[i].nxt){
int v=ed[i].to;
if(v==f)continue;
dfs1(v,u,d+1);
sz[u]+=sz[v];
if(son[u]==-1||sz[son[u]]<sz[v])son[u]=v;
}
}
void dfs2(int u,int tp){
top[u]=tp;
p[u]=pos++;
if(son[u]==-1)return;
dfs2(son[u],tp);
for(int i=head[u];~i;i=ed[i].nxt){
int v=ed[i].to;
if(v!=son[u]&&v!=fa[u]){
dfs2(v,v);
}
}
}
struct T{
int l,r,ma,mi,f;
}stu[maxn*4];
void pushup(int rt){
stu[rt].ma=max(stu[rt<<1].ma,stu[(rt<<1)+1].ma);
stu[rt].mi=min(stu[rt<<1].mi,stu[(rt<<1)+1].mi);
}
void pushdown(int rt){
if(stu[rt].l==stu[rt].r)return;
if(stu[rt].f){
int lson=rt<<1,rson=(rt<<1)|1;
stu[lson].mi=-stu[lson].mi;
stu[lson].ma=-stu[lson].ma;
swap(stu[lson].mi,stu[lson].ma);
stu[rson].mi=-stu[rson].mi;
stu[rson].ma=-stu[rson].ma;
swap(stu[rson].mi,stu[rson].ma);
stu[lson].f^=1;
stu[rson].f^=1;
stu[rt].f=0;
}
}
void build(int l,int r,int rt){
stu[rt].l=l,stu[rt].r=r;stu[rt].f=0;
if(l==r){
stu[rt].mi=stu[rt].ma=g[l];
return ;
}
int mid=(l+r)>>1;
build(l,mid,rt<<1);
build(mid+1,r,(rt<<1)+1);
pushup(rt);
return ;
}
void qf(int l,int r,int rt){
if(stu[rt].l==l&&stu[rt].r==r)
{ stu[rt].mi=-stu[rt].mi;
stu[rt].ma=-stu[rt].ma;
swap(stu[rt].mi,stu[rt].ma);
stu[rt].f^=1;
return ;}
pushdown(rt);
int mid=(stu[rt].l+stu[rt].r)>>1;
if(mid>=r)qf(l,r,rt<<1);
else if(mid<l)qf(l,r,(rt<<1)+1);
else qf(l,mid,rt<<1),qf(mid+1,r,(rt<<1)+1);
pushup(rt);
}
void update(int a,int b,int rt){
if(stu[rt].l==stu[rt].r)
{stu[rt].mi=stu[rt].ma=b;
stu[rt].f=0;
return ;}
pushdown(rt);
int mid=(stu[rt].l+stu[rt].r)>>1;
if(a>mid)update(a,b,(rt<<1)+1);
else update(a,b,rt<<1);
pushup(rt);
}
int q(int l,int r,int rt){
if(stu[rt].l==l&&stu[rt].r==r)return stu[rt].ma;
pushdown(rt);
int mid=(stu[rt].l+stu[rt].r)>>1;
if(mid>=r)return q(l,r,rt<<1);
else if(mid<l)return q(l,r,(rt<<1)+1);
else return max(q(l,mid,rt<<1),q(mid+1,r,(rt<<1)+1));
pushup(rt);
}
int getma(int u,int v){
int f1=top[u],f2=top[v];
int ans=-1000000;
while(f1!=f2){
if(dep[f1]<dep[f2]){
swap(f1,f2);
swap(u,v);
}
ans=max(ans,q(p[f1],p[u],1));
u=fa[f1];
f1=top[u];
}
if(u==v)return ans;
if(dep[u]<dep[v])swap(u,v);
ans=max(ans,q(p[son[v]],p[u],1));
return ans;
}
void nete(int u,int v){
int f1=top[u],f2=top[v];
while(f1!=f2){
if(dep[f1]<dep[f2]){
swap(f1,f2);
swap(u,v);
}
qf(p[f1],p[u],1);
u=fa[f1];
f1=top[u];
}
if(u==v)return ;
if(dep[u]<dep[v])swap(u,v);
qf(p[son[v]],p[u],1);
}
int uu[maxn];
void init(){
memset(head,-1,sizeof(head));
cnt=0;
memset(son,-1,sizeof(son));
pos=0;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
init();
int n;
scanf("%d",&n);
for(int i=1;i<n;i++){
int u,v,vl;
scanf("%d%d%d",&u,&v,&vl);
addedge(u,v,vl);
addedge(v,u,vl);
}
dfs1(1,0,0);
dfs2(1,1);
for(int i=0;i<cnt;i+=2){
int v=ed[i].to,vl=ed[i].vl;
int u=ed[i^1].to;
if(dep[u]<dep[v])swap(u,v);
g[p[u]]=vl;
uu[i/2+1]=u;
}
build(0,n-1,1);
char str[10];
while(~scanf("%s",str)){
if(str[0]=='D')break;
int a,b;
scanf("%d%d",&a,&b);
if(str[0]=='C'){
update(p[uu[a]],b,1);
}
else if(str[0]=='N'){
nete(a,b);
}
else printf("%d\n",getma(a,b));
}
}
return 0;
}