这该死的码农题……
把每一条边变为它连接的两个点中深度较浅的那一个,然后就是一堆单点修改/路径查询,不讲了
这里就讲一下怎么搞路径取反,只要打一个标记就好了,然后把区间和取反,最大最小值交换然后再取反
单点修改的时候忘记pushdown结果调了好久……
//minamoto
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,:;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,:;}
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getchar()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getchar());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
char sr[<<],z[];int K=-,Z;
inline void Ot(){fwrite(sr,,K+,stdout),K=-;}
inline void print(int x){
if(K><<)Ot();if(x<)sr[++K]=,x=-x;
while(z[++Z]=x%+,x/=);
while(sr[++K]=z[Z],--Z);sr[++K]='\n';
}
const int N=;
int head[N],Next[N<<],ver[N<<],edge[N<<],tot=;
inline void add(int u,int v,int e){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e;
}
int dfn[N],top[N],sz[N],son[N],num[N],val[N],dep[N],fa[N],cnt,n,m;
void dfs1(int u){
sz[u]=,dep[u]=dep[fa[u]]+;
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(v!=fa[u]){
fa[v]=u,num[i>>]=v,dfs1(v),sz[u]+=sz[v];
if(sz[son[u]]<sz[v]) son[u]=v;
}
}
}
void dfs2(int u,int t){
top[u]=t,dfn[u]=++cnt;
if(son[u]){
dfs2(son[u],t);
for(int i=head[u];i;i=Next[i])
if(ver[i]!=fa[u]&&ver[i]!=son[u])
dfs2(ver[i],ver[i]);
}
}
int mx[N<<],mn[N<<],sum[N<<],rev[N<<];
#define ls (p<<1)
#define rs (p<<1|1)
inline void upd(int p){
mx[p]=max(mx[ls],mx[rs]),mn[p]=min(mn[ls],mn[rs]),sum[p]=sum[ls]+sum[rs];
}
inline void ppd(int p){
rev[p]^=,sum[p]=-sum[p],swap(mn[p],mx[p]),mn[p]=-mn[p],mx[p]=-mx[p];
}
inline void pd(int p){
if(rev[p]){
ppd(ls),ppd(rs);
rev[p]=;
}
}
void build(int p,int l,int r){
if(l==r) return (void)(mx[p]=mn[p]=sum[p]=val[l]);
int mid=(l+r)>>;
build(ls,l,mid),build(rs,mid+,r);
upd(p);
}
void update(int p,int l,int r,int x){
if(l==r) return (void)(mn[p]=mx[p]=sum[p]=val[l]);
int mid=(l+r)>>;pd(p);
x<=mid?update(ls,l,mid,x):update(rs,mid+,r,x);
upd(p);
}
void Rev(int p,int l,int r,int ql,int qr){
if(ql<=l&&qr>=r) return (void)(ppd(p));
int mid=(l+r)>>;pd(p);
if(ql<=mid) Rev(ls,l,mid,ql,qr);
if(qr>mid) Rev(rs,mid+,r,ql,qr);
upd(p);
}
int querysum(int p,int l,int r,int ql,int qr){
if(ql<=l&&qr>=r) return sum[p];
int mid=(l+r)>>,res=;pd(p);
if(ql<=mid) res+=querysum(ls,l,mid,ql,qr);
if(qr>mid) res+=querysum(rs,mid+,r,ql,qr);
return res;
}
int querymax(int p,int l,int r,int ql,int qr){
if(ql<=l&&qr>=r) return mx[p];
int mid=(l+r)>>,res=-inf;pd(p);
if(ql<=mid) cmax(res,querymax(ls,l,mid,ql,qr));
if(qr>mid) cmax(res,querymax(rs,mid+,r,ql,qr));
return res;
}
int querymin(int p,int l,int r,int ql,int qr){
if(ql<=l&&qr>=r) return mn[p];
int mid=(l+r)>>,res=inf;pd(p);
if(ql<=mid) cmin(res,querymin(ls,l,mid,ql,qr));
if(qr>mid) cmin(res,querymin(rs,mid+,r,ql,qr));
return res;
}
void change(int i,int x){
val[dfn[num[i]]]=x,update(,,n,dfn[num[i]]);
}
void RRR(int u,int v){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
Rev(,,n,dfn[top[u]],dfn[u]);u=fa[top[u]];
}
if(u!=v){
if(dep[u]<dep[v]) swap(u,v);
Rev(,,n,dfn[son[v]],dfn[u]);
}
}
int SUM(int u,int v){
int res=;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
res+=querysum(,,n,dfn[top[u]],dfn[u]);u=fa[top[u]];
}
if(u!=v){
if(dep[u]<dep[v]) swap(u,v);
res+=querysum(,,n,dfn[son[v]],dfn[u]);
}
return res;
}
int MAX(int u,int v){
int res=-inf;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
cmax(res,querymax(,,n,dfn[top[u]],dfn[u]));u=fa[top[u]];
}
if(u!=v){
if(dep[u]<dep[v]) swap(u,v);
cmax(res,querymax(,,n,dfn[son[v]],dfn[u]));
}
return res;
}
int MIN(int u,int v){
int res=inf;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
cmin(res,querymin(,,n,dfn[top[u]],dfn[u]));u=fa[top[u]];
}
if(u!=v){
if(dep[u]<dep[v]) swap(u,v);
cmin(res,querymin(,,n,dfn[son[v]],dfn[u]));
}
return res;
}
char s[];
int main(){
// freopen("testdata.in","r",stdin);
n=read();
for(int i=,u,v,e;i<n;++i)
u=read()+,v=read()+,e=read(),add(u,v,e),add(v,u,e);
dfs1(),dfs2(,);
for(int i=;i<n;++i) val[dfn[num[i]]]=edge[i<<];
build(,,n);
m=read();
while(m--){
scanf("%s",s+);int u=read()+,v=read()+;
switch(s[]){
case 'C':--u,--v,change(u,v);break;
case 'N':RRR(u,v);break;
case 'S':print(SUM(u,v));break;
default:{
print(s[]=='A'?MAX(u,v):MIN(u,v));
break;
}
}
}
Ot();
return ;
}