#include #include #include #include #include #include #include #include #include using namespace std; const int maxn=100010; struct Edge{ int to; int next; }edge[maxn*2]; int head[maxn],tot; int top[maxn];//top[v]表示v所在的重链的顶端节点 int fa[maxn];//父亲节点 int deep[maxn];//深度 int num[maxn];//num[v]表示以v为根的子树的节点数 int p[maxn];//p[v]表示v与其父亲节点的连边在线段树中的位置 int fp[maxn];//和p数组相反 int son[maxn];//重儿子 int pos; int e[maxn][3]; void init() { tot=0; memset(head,-1,sizeof(head)); pos=0; memset(son,-1,sizeof(son)); } void add(int u,int v) { edge[tot].to=v; edge[tot].next=head[u]; head[u]=tot++; } void dfs1(int u,int father,int dep)//第一遍dfs求出fa,deep,num,son { deep[u]=dep; fa[u]=father; num[u]=1; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if(v!=father) { dfs1(v,u,dep+1); num[u]+=num[v]; if(son[u]==-1||num[son[u]]mid) return query(i*2+1,l,r); else { return max(query(i*2,l,mid),query(i*2+1,mid+1,r)); } pushup(i); } int findmax(int u,int v)//查询u->v边的最大值 { int f1=top[u]; int f2=top[v]; int tmp=-100000000; while(f1!=f2) { if(deep[f1]deep[v]) swap(u,v); return max(tmp,query(1,p[son[u]],p[v])); } void Negate1(int i,int l,int r)// 更新线段树的区间[l,r]取反 { if(q[i].l==l&&q[i].r==r) { q[i].maxx=-q[i].maxx; q[i].minn=-q[i].minn; swap(q[i].maxx,q[i].minn); q[i].nege^=1; return; } pushdown(i); int mid=(q[i].l+q[i].r)/2; if(r<=mid) Negate1(i*2,l,r); else if(l>mid) Negate1(i*2+1,l,r); else { Negate1(i*2,l,mid); Negate1(i*2+1,mid+1,r); } pushup(i); } void Negate(int u,int v)//把u-v路径上的边的值都设置为val { int f1=top[u]; int f2=top[v]; while(f1!=f2) { if(deep[f1]deep[v]) swap(u,v); return Negate1(1,p[son[u]],p[v]); } int main(void) { int i,j,k,t,n; scanf("%d",&t); while(t--) { init(); scanf("%d",&n); for(i=0;ideep[e[i][1]]) swap(e[i][0],e[i][1]); update(1,p[e[i][1]],e[i][2]); } char op[10]; int x,y; while(scanf("%s",op)!=EOF) { if(op[0]=='D') break; scanf("%d%d",&x,&y); if(op[0]=='Q') printf("%d\n",findmax(x,y));//查询x->y路径上边权的最大值 else if(op[0]=='C') update(1,p[e[x-1][1]],y);//改变第x条边的值为y else Negate(x,y); } } return 0; }