TLE前9个点,WA最后一个
#include<bits/stdc++.h>
using namespace std;
//#define getchar getchar_unlocked //关闭调试
//#define putchar putchar_unlocked
int read(){
int x=0,t=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')t=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*t;
}
void write(int x){
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');return;
}
const int N=2e5+10;
vector<pair<int,int> >g[N];
int n,m,now_edge[N],a[N];
int fa[N],dep[N],siz[N],son[N],eg[N];
void dfs1(int x,int from){
fa[x]=from;
dep[x]=dep[from]+1;
siz[x]=1;
for(int i=0;i<g[x].size();i++){
int y=g[x][i].first;
if(y==from)continue;
eg[g[x][i].second]=y;
dfs1(y,x);
siz[x]+=siz[y];
if(siz[son[x]]<siz[y])son[x]=y;
}
}
int in[N],out[N],tot,top[N];
void dfs2(int x,int tp,int from){
top[x]=tp;
in[x]=++tot;
if(!son[x])return ;
dfs2(son[x],tp,x);
for(int i=0;i<g[x].size();i++){
int y=g[x][i].first;
if(y==son[x]||y==from)continue;
dfs2(y,y,x);
}out[x]=tot;
}
int mx[N*4],mn[N*4],sm[N*4],lazy[N*4];
void build(int l,int r,int m){
if(l==r){
mx[m]=mn[m]=sm[m]=a[l],lazy[m]=1;
// printf("mx[%d]=%d mn[%d]=%d sm[%d]=%d \n",m,mx[m],m,mn[m],m,sm[m]);
}
else {
int mid=l+r>>1;
build(l,mid,m*2);
build(mid+1,r,m*2+1);
mx[m]=max(mx[m*2],mx[m*2+1]);
mn[m]=min(mn[m*2],mn[m*2+1]);
sm[m]=sm[m*2]+sm[m*2+1];
// printf("mx[%d]=%d mn[%d]=%d sm[%d]=%d \n",m,mx[m],m,mn[m],m,sm[m]);
lazy[m]=1;
}
}
void push_down(int m){
if(lazy[m]==-1){
swap(mx[m*2],mn[m*2]);
swap(mx[m*2+1],mn[m*2+1]);
mx[m*2]=-mx[m*2];mn[m*2]=-mn[m*2];sm[m*2]=-sm[m*2];
mx[m*2+1]=-mx[m*2+1];mn[m*2+1]=-mn[m*2+1];sm[m*2+1]=-sm[m*2+1];
lazy[m*2]*=-1;lazy[m*2+1]*=-1;
}
}
void push_up(int m){
mx[m]=max(mx[m*2],mx[m*2+1]);
mn[m]=min(mn[m*2],mn[m*2+1]);
sm[m]=sm[m*2]+sm[m*2+1];
lazy[m]=1;
}
void add(int l,int r,int x,int k,int m){
if(l==r)mx[m]=mn[m]=sm[m]=k,lazy[m]=1;
else {
int mid=l+r>>1;
push_down(m);
if(x<=mid)add(l,mid,x,k,m*2);
else add(mid+1,r,x,k,m*2+1);
push_up(m);
}
// printf("l=%d r=%d sum[%d]=%d max[%d]=%d min[%d]=%d\n",l,r,m,sm[m],m,mx[m],m,mn[m]);
}
struct answer{int Sum,Max,Min;};
answer get_best(answer x,answer y){return (answer){x.Sum+y.Sum ,max(x.Max ,y.Max ),min(x.Min ,y.Min )};}
answer ask(int l,int r,int x,int y,int m){//cout<<"***"<<l<<" "<<r<<"***"<<endl;
if(x<=l&&r<=y)return (answer){sm[m],mx[m],mn[m]};
else {
int mid=(l+r)/2;
answer ans1=(answer){0,0,0},ans2=(answer){0,0,0};
push_down(m);
if(x<=mid)ans1=ask(l,mid,x,y,m*2);
if(y>mid)ans2=ask(mid+1,r,x,y,m*2+1);
push_up(m);
// cout<<"l="<<l<<" mid="<<mid<<" ans1={"<<ans1.Sum <<" "<<ans1.Max <<" "<<ans1.Min <<"}\n";
// cout<<"mid="<<mid<<" r="<<r<<" ans2={"<<ans2.Sum <<" "<<ans2.Max <<" "<<ans2.Min <<"}\n";
return get_best(ans1,ans2);
}
}
void change(int l,int r,int x,int y,int m){
if(x<=l&&r<=y)lazy[m]=-lazy[m],swap(mx[m],mn[m]),mx[m]=-mx[m],mn[m]=-mn[m],sm[m]=-sm[m];
else {
int mid=l+r>>1;
push_down(m);
if(x<=mid)change(l,mid,x,y,m*2);
if(y>mid)change(mid+1,r,x,y,m*2+1);
push_up(m);
}
}
void xg(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
change(1,n,in[top[x]],in[x],1);
x=top[x];
}
if(x==y)return ;
if(dep[x]>dep[y])swap(x,y);
change(1,n,in[son[x]],in[y],1);
}
answer xz(int x,int y){
answer best=(answer){0,-0x3f3f3f3f,0x3f3f3f3f};
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
best=get_best(best,ask(1,n,in[top[x]],in[x],1));
// printf("x=%d y=%d best={%d,%d,%d}\n",top[x],in[x],best.Sum ,best.Max,best.Min );
x=top[x];
}
if(x==y)return best;
if(dep[x]>dep[y])swap(x,y);
best=get_best(best,ask(1,n,in[son[x]],in[y],1));
// printf("x=%d y=%d best={%d,%d,%d}*\n",son[x],y,best.Sum ,best.Max,best.Min );
return best;
}
int main(){
n=read();
for(int i=1;i<n;i++){
int u=read(),v=read(),w=read();u++;v++;
g[u].push_back(make_pair(v,i));
g[v].push_back(make_pair(u,i));
now_edge[i]=w;
}
dfs1(1,0);
dfs2(1,1,0);
for(int i=1;i<n;i++)
a[eg[i]]=now_edge[i];
m=read();
build(1,n,1);
while(m--){
char c;
do{c=getchar();
}while(c==10||c==32);
if(c=='C'){
int u=read(),w=read();
add(1,n,in[eg[u]],w,1);
}
else if(c=='N'){
int u=read(),v=read();u++;v++;
xg(u,v);
}
else if(c=='S'){
c=getchar();c=getchar();
int u=read(),v=read();u++;v++;
write(xz(u,v).Sum);
putchar('\n');
}
else if(c=='M'){
c=getchar();c=getchar();
int u=read(),v=read();u++;v++;
if(c=='X')write(xz(u,v).Max);
else write(xz(u,v).Min);
putchar('\n');
}
}
return 0;
}