dfs把边权送给点权
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #include <vector> #include <string> using namespace std; #define ll long long #define re register #define pb push_back #define fi first #define se second const int N=1e6+10; const int mod=998244353; void read(int &a) { a=0;int d=1;char ch; while(ch=getchar(),ch>'9'||ch<'0') if(ch=='-') d=-1; a=ch^48; while(ch=getchar(),ch>='0'&&ch<='9') a=(a<<3)+(a<<1)+(ch^48); a*=d; } struct node{int x,w,p;}; struct note { int l,r,ma,mi,sum,lazy; }tree[N<<2]; vector <node> v[N]; int siz[N],top[N],dep[N],son[N],id[N],rk[N],f[N],val[N],rt=1,cnt,head[N]; void dfs1(int x) { siz[x]=1,dep[x]=dep[f[x]]+1; for(re int t=0;t<v[x].size();t++) { node i=v[x][t]; if(i.x!=f[x]) { val[i.x]=i.w; head[i.p]=i.x; f[i.x]=x,dfs1(i.x); siz[x]+=siz[i.x]; if(siz[son[x]]<siz[i.x]) son[x]=i.x; } } } void dfs2(int x,int tp) { top[x]=tp,id[x]=++cnt,rk[cnt]=x; if(son[x]) dfs2(son[x],tp); for(re int t=0;t<v[x].size();t++) {node i=v[x][t];if(i.x!=son[x]&&i.x!=f[x]) dfs2(i.x,i.x);} } void build(int l,int r,int now) { tree[now].l=l,tree[now].r=r,tree[now].lazy=0; if(l==r) {tree[now].sum=val[rk[l]],tree[now].ma=val[rk[l]],tree[now].mi=val[rk[l]];return;} int m=l+r>>1; build(l,m,now<<1),build(m+1,r,now<<1|1); tree[now].sum=(tree[now<<1].sum+tree[now<<1|1].sum); tree[now].mi=min(tree[now<<1].mi,tree[now<<1|1].mi); tree[now].ma=max(tree[now<<1].ma,tree[now<<1|1].ma); } void work(int now,int k) { tree[now].sum=-tree[now].sum; int x=tree[now].ma,y=tree[now].mi; tree[now].ma=-y,tree[now].mi=-x; tree[now].lazy^=k; } void pushdown(int now) { work(now<<1,tree[now].lazy); work(now<<1|1,tree[now].lazy); tree[now].lazy=0; } void modify(int l,int r,int now,int w) { if(l<=tree[now].l&&tree[now].r<=r) {work(now,w);return;} if(tree[now].lazy) pushdown(now); int m=tree[now].l+tree[now].r>>1; if(m>=l) modify(l,r,now<<1,w); if(m<r) modify(l,r,now<<1|1,w); tree[now].sum=(tree[now<<1].sum+tree[now<<1|1].sum); tree[now].ma=max(tree[now<<1].ma,tree[now<<1|1].ma); tree[now].mi=min(tree[now<<1].mi,tree[now<<1|1].mi); } void mo(int l,int now,int w) { if(tree[now].l==l&&tree[now].r==l) {tree[now].sum=w,tree[now].ma=w,tree[now].mi=w;return;} if(tree[now].lazy) pushdown(now); int m=tree[now].l+tree[now].r>>1; if(m>=l) mo(l,now<<1,w); if(m<l) mo(l,now<<1|1,w); tree[now].sum=(tree[now<<1].sum+tree[now<<1|1].sum); tree[now].mi=min(tree[now<<1].mi,tree[now<<1|1].mi); tree[now].ma=max(tree[now<<1].ma,tree[now<<1|1].ma); } int query(int l,int r,int now) { int ans=0; if(l<=tree[now].l&&tree[now].r<=r) {return tree[now].sum;} if(tree[now].lazy) pushdown(now); int m=tree[now].l+tree[now].r>>1; if(m>=l) ans+=query(l,r,now<<1); if(m<r) ans+=query(l,r,now<<1|1); return ans; } int queryy(int l,int r,int now) { int ans=-0x3fffffff; if(l<=tree[now].l&&tree[now].r<=r) {return tree[now].ma;} if(tree[now].lazy) pushdown(now); int m=tree[now].l+tree[now].r>>1; if(m>=l) ans=max(ans,queryy(l,r,now<<1)); if(m<r) ans=max(ans,queryy(l,r,now<<1|1)); return ans; } int queryyy(int l,int r,int now) { int ans=0x3fffffff; if(l<=tree[now].l&&tree[now].r<=r) {return tree[now].mi;} if(tree[now].lazy) pushdown(now); int m=tree[now].l+tree[now].r>>1; if(m>=l) ans=min(ans,queryyy(l,r,now<<1)); if(m<r) ans=min(ans,queryyy(l,r,now<<1|1)); return ans; } void update(int x,int y,int w) { while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) swap(x,y); modify(id[top[x]],id[x],1,w); x=f[top[x]]; } if(dep[x]>dep[y]) swap(x,y); modify(id[x]+1,id[y],1,w); } int query1(int x,int y) { int ans=0; while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) swap(x,y); ans+=query(id[top[x]],id[x],1); x=f[top[x]]; } if(dep[x]>dep[y]) swap(x,y); return ans+query(id[x]+1,id[y],1); } int query2(int x,int y) { int ans=-0x3fffffff; while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) swap(x,y); ans=max(ans,queryy(id[top[x]],id[x],1)); x=f[top[x]]; } if(dep[x]>dep[y]) swap(x,y); return ans=max(ans,queryy(id[x]+1,id[y],1)); } int query3(int x,int y) { int ans=0x3fffffff; while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) swap(x,y); ans=min(ans,queryyy(id[top[x]],id[x],1)); x=f[top[x]]; } if(dep[x]>dep[y]) swap(x,y); return ans=min(ans,queryyy(id[x]+1,id[y],1)); } int main() { int n;read(n); for(re int i=1,x,y,z;i<n;i++) { read(x),read(y),read(z); x++,y++; v[x].pb(node{y,z,i}); v[y].pb(node{x,z,i}); } dfs1(rt),dfs2(rt,rt); build(1,n,1); int m;read(m); char op[10]; for(re int i=1,l,r;i<=m;i++) { scanf("%s",op); read(l),read(r); l++,r++; if(op[0]=='C') l--,r--,mo(id[head[l]],1,r); else if(op[0]=='N') update(l,r,1); else if(op[0]=='S') printf("%d ",query1(l,r)); else if(op[0]=='M'&&op[1]=='A') printf("%d ",query2(l,r)); else if(op[0]=='M'&&op[1]=='I') printf("%d ",query3(l,r)); } return 0; }