调了四天了,仍然是 8 分。
//2021/12/14
//2021/12/27
//2021/12/29
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <climits>//need "INT_MAX","INT_MIN"
#include <cstring>//need "memset"
#include <algorithm>
#define enter() putchar(10)
#define debug(c,que) cerr<<#c<<" = "<<c<<que
#define cek(c) puts(c)
#define blow(arr,st,ed,w) for(register int i=(st);i<=(ed);i++)cout<<arr[i]<<w;
#define speed_up() cin.tie(0),cout.tie(0)
#define endl "\n"
#define Input_Int(n,a) for(register int i=1;i<=n;i++)scanf("%d",a+i);
#define Input_Long(n,a) for(register long long i=1;i<=n;i++)scanf("%lld",a+i);
#define mst(a,k) memset(a,k,sizeof(a))
namespace Newstd
{
inline int read()
{
int x=0,k=1;
char ch=getchar();
while(ch<'0' || ch>'9')
{
if(ch=='-')
{
k=-1;
}
ch=getchar();
}
while(ch>='0' && ch<='9')
{
x=(x<<1)+(x<<3)+ch-'0';
ch=getchar();
}
return x*k;
}
inline void write(int x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9)
{
write(x/10);
}
putchar(x%10+'0');
}
}
using namespace Newstd;
using namespace std;
const int INF=0x3f3f3f3f;
const int ma=200005;
struct Gragh
{
int v;
int w;
int nxt;
};
Gragh gra[ma<<1];
int a[ma],head[ma],top[ma],son[ma],siz[ma],dep[ma],fa[ma],rev[ma],dfn[ma];
int Min[ma<<2],Max[ma<<2],sum[ma<<2];
bool chg[ma<<2];
int n,m;
int idx,cnt;
namespace Segment_Tree
{
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
inline void add(int u,int v,int w)
{
gra[++idx].v=v;
gra[idx].w=w;
gra[idx].nxt=head[u];
head[u]=idx;
}
inline void pushup(int p)
{
Max[p]=max(Max[ls(p)],Max[rs(p)]);
Min[p]=min(Min[ls(p)],Min[rs(p)]);
sum[p]=sum[ls(p)]+sum[rs(p)];
}
inline void build(int p,int l,int r)
{
if(l==r)
{
Min[p]=Max[p]=sum[p]=a[rev[l]];
return;
}
int mid=(l+r)>>1;
Segment_Tree::build(ls(p),l,mid);
Segment_Tree::build(rs(p),mid+1,r);
Segment_Tree::pushup(p);
}
inline void updata_opp(int p,int l,int r)
{
chg[p]^=1;//取反
sum[p]=-sum[p],Min[p]=-Min[p],Max[p]=-Max[p];
}
inline void pushdown(int p,int l,int r)
{
if(l==r)
{
chg[p]=false;
return;
}
int mid=(l+r)>>1;
Segment_Tree::updata_opp(ls(p),l,mid);
Segment_Tree::updata_opp(rs(p),mid+1,r);
chg[p]=false;
}
inline void updata(int pos,int l,int r,int p,int k)
{
if(l==r)
{
Min[p]=Max[p]=sum[p]=k;
return;
}
int mid=(l+r)>>1;
if(chg[p]==true)
{
Segment_Tree::pushdown(p,l,r);
}
if(pos<=mid)
{
Segment_Tree::updata(pos,l,mid,ls(p),k);
}
else
{
Segment_Tree::updata(pos,mid+1,r,rs(p),k);
}
Segment_Tree::pushup(p);
}
inline void updata_side_opp(int nl,int nr,int l,int r,int p)
{
if(nl<=l && r<=nr)
{
Segment_Tree::updata_opp(p,l,r);
return;
}
if(chg[p]==true)
{
Segment_Tree::pushdown(p,l,r);
}
int mid=(l+r)>>1;
if(nl<=mid)
{
Segment_Tree::updata_side_opp(nl,nr,l,mid,ls(p));
}
if(nr>mid)
{
Segment_Tree::updata_side_opp(nl,nr,mid+1,r,rs(p));
}
Segment_Tree::pushup(p);
}
inline int query(int nl,int nr,int l,int r,int p,int opt)
{
if(nl<=l && r<=nr)
{
if(opt==1)
{
return sum[p];
}
else if(opt==2)
{
return Max[p];
}
return Min[p];
}
int mid=(l+r)>>1,res;
if(chg[p]==true)
{
Segment_Tree::pushdown(p,l,r);
}
if(opt==1)
{
res=0;
if(nl<=mid)
{
res+=Segment_Tree::query(nl,nr,l,mid,ls(p),opt);
}
if(nr>mid)
{
res+=Segment_Tree::query(nl,nr,mid+1,r,rs(p),opt);
}
return res;
}
else if(opt==2)
{
res=-INF;
if(nl<=mid)
{
res=max(res,Segment_Tree::query(nl,nr,l,mid,ls(p),opt));
}
if(nr>mid)
{
res=max(res,Segment_Tree::query(nl,nr,mid+1,r,rs(p),opt));
}
return res;
}
res=INF;
if(nl<=mid)
{
res=min(res,Segment_Tree::query(nl,nr,l,mid,ls(p),opt));
}
if(nr>mid)
{
res=min(res,Segment_Tree::query(nl,nr,mid+1,r,rs(p),opt));
}
return res;
}
#undef ls
#undef rs
}
namespace Chain
{
inline void dfs1(int now,int fath,int depth,int side_val)
{
fa[now]=fath;
dep[now]=depth;
siz[now]=1;
a[now]=side_val;
for(register int i=head[now];i;i=gra[i].nxt)
{
int v=gra[i].v,w=gra[i].w;
if(v!=fath)
{
dfs1(v,now,depth+1,w);
siz[now]+=siz[v];
if(siz[son[now]]<siz[v])
{
son[now]=v;
}
}
}
}
inline void dfs2(int now,int topf)
{
top[now]=topf;
dfn[now]=++cnt;
rev[cnt]=now;
if(son[now]!=0)
{
dfs2(son[now],topf);
for(register int i=head[now];i;i=gra[i].nxt)
{
int v=gra[i].v;
if(v!=fa[now] && v!=son[now])
{
dfs2(v,v);
}
}
}
}
inline int query(int x,int y,int opt)
{
int res;
if(opt==1)
{
res=0;
}
else if(opt==2)
{
res=-INF;
}
else
{
res=INF;
}
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
{
swap(x,y);
}
if(opt==1)
{
res+=Segment_Tree::query(dfn[top[x]],dfn[x],1,n,1,opt);
}
else if(opt==2)
{
res=max(res,Segment_Tree::query(dfn[top[x]],dfn[x],1,n,1,opt));
}
else
{
res=min(res,Segment_Tree::query(dfn[top[x]],dfn[x],1,n,1,opt));
}
x=fa[top[x]];
}
if(dep[x]>dep[y])
{
swap(x,y);
}
if(dfn[x]==dfn[y])
{
return res;
}
if(opt==1)
{
res+=Segment_Tree::query(dfn[x]+1,dfn[y],1,n,1,opt);
}
else if(opt==2)
{
res=max(res,Segment_Tree::query(dfn[x]+1,dfn[y],1,n,1,opt));
}
else
{
res=min(res,Segment_Tree::query(dfn[x]+1,dfn[y],1,n,1,opt));
}
return res;
}
inline void updata_side(int x,int y)
{
int ta=gra[x<<1].v,tb=gra[(x<<1)-1].v;
if(ta==fa[tb])
{
Segment_Tree::updata(dfn[tb],1,n,1,y);
}
else
{
Segment_Tree::updata(dfn[ta],1,n,1,y);
}
}
inline void updata_opp(int x,int y)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
{
swap(x,y);
}
Segment_Tree::updata_side_opp(dfn[top[x]],dfn[x],1,n,1);
x=fa[top[x]];
}
if(dep[x]>dep[y])
{
swap(x,y);
}
if(dfn[x]+1<=dfn[y])
{
Segment_Tree::updata_side_opp(dfn[x]+1,dfn[y],1,n,1);
}
}
}
int main(void)
{
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
n=read();
for(register int i=1;i<n;i++)
{
int u=read()+1,v=read()+1,w=read();
Segment_Tree::add(u,v,w),Segment_Tree::add(v,u,w);
}
m=read();
Chain::dfs1(1,0,1,0),Chain::dfs2(1,1);
Segment_Tree::build(1,1,n);
while(m--)
{
string tmp;
cin>>tmp;
int x=read()+1,y=read()+1;
if(tmp=="C")
{
Chain::updata_side(x-1,y-1);
}
else if(tmp=="N")
{
Chain::updata_opp(x,y);
}
else
{
int opt;
if(tmp=="SUM")
{
opt=1;
}
else if(tmp=="MAX")
{
opt=2;
}
else
{
opt=3;
}
printf("%d\n",Chain::query(x,y,opt));
}
}
return 0;
}