思路:
树链剖分,边权转点权;
线段树维护三个东西,sum,max,min;
当一个区间变成相反数时,sum=-sum,max=-min,min=-max;
来,上代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define maxn 100005 #define ll long long #define INF 0x7fffffff struct TreeNodeType { ll l,r,mi,ma,sum,mid,flag; }; struct TreeNodeType tree[maxn<<2]; ll n,m,E[maxn<<1],V[maxn<<1],W[maxn<<1],cnt; ll deep[maxn],ps[maxn],pe[maxn],head[maxn],X,ty; ll f[maxn],id[maxn],ds[maxn],size[maxn],top[maxn]; inline void in(ll &now) { ll if_z=1;now=0; char Cget=getchar(); while(Cget>'9'||Cget<'0') { if(Cget=='-') if_z=-1; Cget=getchar(); } while(Cget>='0'&&Cget<='9') { now=now*10+Cget-'0'; Cget=getchar(); } now*=if_z; } inline void edge_add(ll u,ll v,ll w) { E[++cnt]=head[u],V[cnt]=v,W[cnt]=w,head[u]=cnt; E[++cnt]=head[v],V[cnt]=u,W[cnt]=w,head[v]=cnt; } void pre(ll now,ll fa) { f[now]=fa,size[now]=1; if(fa==-1) deep[now]=1; else deep[now]=deep[fa]+1; for(ll i=head[now];i;i=E[i]) { if(V[i]==fa) continue; pre(V[i],now),size[now]+=size[V[i]]; } } void dfs(ll now,ll chain,ll dis) { ll pos=n+1,ww; top[now]=chain,id[now]=++cnt,ds[cnt]=dis; for(ll i=head[now];i;i=E[i]) { if(V[i]==f[now]) continue; if(size[V[i]]>size[pos]) pos=V[i],ww=W[i]; } if(pos==n+1) return ; dfs(pos,chain,ww); for(ll i=head[now];i;i=E[i]) { if(V[i]==pos||V[i]==f[now]) continue; dfs(V[i],V[i],W[i]); } } void tree_build(ll now,ll l,ll r) { tree[now].l=l,tree[now].r=r; if(l==r) { tree[now].mi=ds[l]; tree[now].ma=ds[l]; tree[now].sum=ds[l]; return ; } tree[now].mid=l+r>>1; tree_build(now<<1,l,tree[now].mid); tree_build(now<<1|1,tree[now].mid+1,r); 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); } inline void tree_down(ll now) { ll mii=tree[now<<1].mi,maa=tree[now<<1].ma; tree[now<<1].ma=-mii,tree[now<<1].mi=-maa; tree[now<<1].sum=-tree[now<<1].sum; mii=tree[now<<1|1].mi,maa=tree[now<<1|1].ma; tree[now<<1|1].mi=-maa,tree[now<<1|1].ma=-mii; tree[now<<1|1].sum=-tree[now<<1|1].sum; tree[now<<1].flag=!tree[now<<1].flag; tree[now<<1|1].flag=!tree[now<<1|1].flag; tree[now].flag=false; } void tree_query(ll now,ll l,ll r) { if(tree[now].l==l&&tree[now].r==r) { if(ty==1) X+=tree[now].sum; else if(ty==2) X=max(X,tree[now].ma); else X=min(X,tree[now].mi); return ; } if(tree[now].flag) tree_down(now); if(l>tree[now].mid) tree_query(now<<1|1,l,r); else if(r<=tree[now].mid) tree_query(now<<1,l,r); else tree_query(now<<1,l,tree[now].mid),tree_query(now<<1|1,tree[now].mid+1,r); } void tree_change(ll now,ll to) { if(tree[now].l==tree[now].r) { tree[now].mi=X; tree[now].ma=X; tree[now].sum=X; return ; } if(tree[now].flag) tree_down(now); if(to<=tree[now].mid) tree_change(now<<1,to); else tree_change(now<<1|1,to); 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 tree_change_(ll now,ll l,ll r) { if(tree[now].l==l&&tree[now].r==r) { tree[now].flag=!tree[now].flag; ll mii=tree[now].mi,maa=tree[now].ma; tree[now].sum=-tree[now].sum; tree[now].ma=-mii,tree[now].mi=-maa; return ; } if(tree[now].flag) tree_down(now); if(l>tree[now].mid) tree_change_(now<<1|1,l,r); else if(r<=tree[now].mid) tree_change_(now<<1,l,r); else tree_change_(now<<1,l,tree[now].mid),tree_change_(now<<1|1,tree[now].mid+1,r); 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 solve_change(ll x,ll y) { while(top[x]!=top[y]) { if(deep[top[x]]<deep[top[y]]) swap(x,y); tree_change_(1,id[top[x]],id[x]); x=f[top[x]]; } if(deep[x]>deep[y]) swap(x,y); if(x!=y) tree_change_(1,id[x]+1,id[y]); } void solve_query(ll x,ll y) { while(top[x]!=top[y]) { if(deep[top[x]]<deep[top[y]]) swap(x,y); tree_query(1,id[top[x]],id[x]); x=f[top[x]]; } if(deep[x]>deep[y]) swap(x,y); if(x!=y) tree_query(1,id[x]+1,id[y]); } int main() { freopen("nt2011_travel.in","r",stdin); freopen("nt2011_travel.out","w",stdout); in(n);ll u,v,w; for(ll i=1;i<n;i++) { in(u),in(v),in(w); edge_add(u,v,w); ps[i]=u,pe[i]=v; } cnt=0,pre(0,-1),dfs(0,0,0); tree_build(1,1,n); in(m);char ch[10]; while(m--) { scanf("%s",ch);in(u),in(v); if(ch[0]=='N') solve_change(u,v); else if(ch[0]=='C') { X=v; if(deep[ps[u]]>deep[pe[u]]) swap(ps[u],pe[u]); tree_change(1,id[pe[u]]); } else if(ch[0]=='S') ty=1,X=0,solve_query(u,v),printf("%lld ",X); else if(ch[0]=='M') { if(ch[1]=='A') ty=2,X=-INF,solve_query(u,v),printf("%lld ",X); else ty=3,X=INF,solve_query(u,v),printf("%lld ",X); } } fclose(stdin),fclose(stdout); return 0; }