树链剖分类模板:
#include<bits/stdc++.h>
#define lowbit(x) ((x)&(-(x)))
#define ll long long
#define INF 0x7fffffff
#define CLR(a) memset(a, 0, sizeof(a))
using namespace std;
#define ls rt<<1
#define rs rt<<1|1
#define MID(a,b) (a+((b-a)>>1))
const int maxn=2e5+10;
struct Edge{
int nxt,to,val;
}edge[maxn];
int head[maxn],cnt,pt,w[maxn],wt[maxn];
int son[maxn],id[maxn],fa[maxn],dep[maxn],size[maxn],top[maxn];
void add(int u,int v,int val){
edge[++cnt].to=v;
edge[cnt].nxt=head[u];
edge[cnt].val=val;
head[u]=cnt;
}
struct node{
int l,r,sum,Min,Max,lazy;
int mid(){return MID(l,r);}
void init(int tmp){
sum=Min=Max=tmp;
}
};
struct Segtree{
node tree[maxn<<2];
void push_up(int rt){
tree[rt].sum=tree[ls].sum+tree[rs].sum;
tree[rt].Max=max(tree[ls].Max,tree[rs].Max);
tree[rt].Min=min(tree[ls].Min,tree[rs].Min);
}
void push_down(int rt){
if(tree[rt].lazy){
tree[ls].sum=-tree[ls].sum;tree[ls].lazy^=1;
tree[rs].sum=-tree[rs].sum;tree[rs].lazy^=1;
int p1,p2,p3,p4;
p1=tree[ls].Min;
p2=tree[ls].Max;
p3=tree[rs].Min;
p4=tree[rs].Max;
tree[ls].Max=-p1;
tree[ls].Min=-p2;
tree[rs].Max=-p3;
tree[rs].Min=-p4;
tree[rt].lazy=0;
}
}
void build(int l,int r,int rt){
tree[rt].l=l;tree[rt].r=r;
if(l==r){
tree[rt].init(wt[l]);
}else{
int mid=tree[rt].mid();
build(l,mid,ls);
build(mid+1,r,rs);
push_up(rt);
}
}
void update(int pos,int rt,int val){//单点更新
int l=tree[rt].l,r=tree[rt].r;
if(l==r) tree[rt].init(val);
else{
push_down(rt);
int mid=tree[rt].mid();
if(pos<=mid) update(pos,ls,val);
else update(pos,rs,val);
push_up(rt);
}
}
void modify(int st,int ed,int rt){//区间修改
int l=tree[rt].l,r=tree[rt].r;
if(st<=l&&r<=ed){
tree[rt].sum=-tree[rt].sum;
tree[rt].lazy^=1;
int p1,p2;
p1=tree[rt].Max;
p2=tree[rt].Min;
tree[rt].Max=-p2;
tree[rt].Min=-p1;
}else{
push_down(rt);
int mid=tree[rt].mid();
if(st<=mid) modify(st,ed,ls);
if(ed>mid) modify(st,ed,rs);
push_up(rt);
}
}
int c_sum(int st,int ed,int rt){
int l=tree[rt].l,r=tree[rt].r;
if(st<=l&&r<=ed) return tree[rt].sum;
else{
push_down(rt);
int mid=tree[rt].mid();
int sum1=0,sum2=0;
if(st<=mid) sum1=c_sum(st,ed,ls);
if(ed>mid) sum2=c_sum(st,ed,rs);
return sum1+sum2;
}
}
int c_max(int st,int ed,int rt){
int l=tree[rt].l,r=tree[rt].r;
if(st<=l&&r<=ed) return tree[rt].Max;
else{
push_down(rt);
int mid=tree[rt].mid();
int mx1=-INF,mx2=-INF;//
if(st<=mid) mx1=c_max(st,ed,ls);
if(ed>mid) mx2=c_max(st,ed,rs);
return max(mx1,mx2);
}
}
int c_min(int st,int ed,int rt){
int l=tree[rt].l,r=tree[rt].r;
if(st<=l&&r<=ed) return tree[rt].Min;
else{
push_down(rt);
int mid=tree[rt].mid();
int mx1=INF,mx2=INF;//
if(st<=mid) mx1=c_min(st,ed,ls);
if(ed>mid) mx2=c_min(st,ed,rs);
return min(mx1,mx2);
}
}
void cal(int x,int y){
int fx=top[x],fy=top[y];
while(fx!=fy){
if(dep[fx]<dep[fy]) swap(x,y),swap(fx,fy);
modify(id[fx],id[x],1);//fx编号比x小,想想为什么?
x=fa[fx],fx=top[x];
}
if(id[x]>id[y]) swap(x,y);
modify(id[x]+1,id[y],1);
}
int q_max(int x,int y){
int fx=top[x],fy=top[y],ans=-INF;
while(fx!=fy){
if(dep[fx]<dep[fy]) swap(x,y),swap(fx,fy);
ans=max(ans,c_max(id[fx],id[x],1));
x=fa[fx],fx=top[x];
}
if(id[x]>id[y]) swap(x,y);
return ans=max(ans,c_max(id[x]+1,id[y],1));
}
int q_min(int x,int y){
int fx=top[x],fy=top[y],ans=INF;
while(fx!=fy){
if(dep[fx]<dep[fy]) swap(x,y),swap(fx,fy);
ans=min(ans,c_min(id[fx],id[x],1));
x=fa[fx],fx=top[x];
}
if(id[x]>id[y]) swap(x,y);
return ans=min(ans,c_min(id[x]+1,id[y],1));
}
int q_sum(int x,int y){
int fx=top[x],fy=top[y],ans=0;
while(fx!=fy){
if(dep[fx]<dep[fy]) swap(x,y),swap(fx,fy);
ans+=c_sum(id[fx],id[x],1);
x=fa[fx],fx=top[x];
}
if(id[x]>id[y]) swap(x,y);
return ans+=c_sum(id[x]+1,id[y],1);
}
}seg;
void dfs_1(int cur,int fath,int deep){
dep[cur]=deep;
fa[cur]=fath;
size[cur]=1;
int maxson=-1;
for(int i=head[cur];i;i=edge[i].nxt){
int to=edge[i].to;
int val=edge[i].val;
if(to==fath) continue;
w[to]=val;
dfs_1(to,cur,deep+1);
size[cur]+=size[to];
if(size[to]>maxson) son[cur]=to,maxson=size[to];
}
}
void dfs_2(int cur,int topf){
id[cur]=++pt;
wt[pt]=w[cur];
top[cur]=topf;
if(!son[cur]) return;
dfs_2(son[cur],topf);
for(int i=head[cur];i;i=edge[i].nxt){
int to=edge[i].to;
if(to==fa[cur]||to==son[cur]) continue;
dfs_2(to,to);
}
}
int n;
int main() {
int u,v,w;
scanf("%d",&n);
for(int i=1;i<n;i++){
scanf("%d%d%d",&u,&v,&w);
u++,v++;
add(u,v,w);
add(v,u,w);
}
dfs_1(1,0,1);
dfs_2(1,1);
seg.build(1,n,1);
int m;scanf("%d",&m);
for(int i=1,x,y;i<=m;i++){
char s1[10];
scanf("%s%d%d",s1,&x,&y);
x++,y++;
if(s1[0]=='C') seg.update(id[x],1,y-1);
if(s1[0]=='N') seg.cal(x,y);
if(s1[0]=='S') printf("%d\n",seg.q_sum(x,y));
if(s1[1]=='I') printf("%d\n",seg.q_min(x,y));
if(s1[1]=='A') printf("%d\n",seg.q_max(x,y));
}
return 0;
}