Description
毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园。 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里。爬啊爬~爬啊爬~~毛毛虫爬到了一颗小小的“毛景树”下面,发现树上长着他最爱吃的毛毛果~~~ “毛景树”上有N个节点和N-1条树枝,但节点上是没有毛毛果的,毛毛果都是长在树枝上的。但是这棵“毛景树”有着神奇的魔力,他能改变树枝上毛毛果的个数: ? Change k w:将第k条树枝上毛毛果的个数改变为w个。 ? Cover u v w:将节点u与节点v之间的树枝上毛毛果的个数都改变为w个。 ? Add u v w:将节点u与节点v之间的树枝上毛毛果的个数都增加w个。 由于毛毛虫很贪,于是他会有如下询问: ? Max u v:询问节点u与节点v之间树枝上毛毛果个数最多有多少个。
Input
第一行一个正整数N。 接下来N-1行,每行三个正整数Ui,Vi和Wi,第i+1行描述第i条树枝。表示第i条树枝连接节点Ui和节点Vi,树枝上有Wi个毛毛果。 接下来是操作和询问,以“Stop”结束。
Output
对于毛毛虫的每个询问操作,输出一个答案。
树链剖分+线段树维护 区间max,区间覆盖标记,区间增加量标记
#include<cstdio> char buf[10000005],*ptr=buf-1; inline int input(){ int x=0,c=*++ptr,f=1; while(c>57||c<48){if(c==‘-‘)f=-1;c=*++ptr;} while(c>47&&c<58)x=x*10+c-48,c=*++ptr; return x*f; } inline int getop(){ int c=*++ptr; while(c<33)c=*++ptr; return *++ptr; } const int N=100050; int mx[N*2],a[N*2],lc[N*2],rc[N*2],p=0,n; bool cov[N*2]; int es[N*2],enx[N*2],ev[N*2],e0[N],v0[N],ep=2; int l,r,ans; int fa[N],dep[N],son[N],sz[N],top[N],v[N],id[N],ei[N][2],idr[N],idp=1; inline int max(int a,int b){return a>b?a:b;} void dwn(int w){ if(a[w]){ if(lc[w]){ a[lc[w]]+=a[w]; mx[lc[w]]+=a[w]; a[rc[w]]+=a[w]; mx[rc[w]]+=a[w]; } a[w]=0; } if(cov[w]){ if(lc[w]){ cov[lc[w]]=cov[rc[w]]=1; mx[lc[w]]=mx[rc[w]]=mx[w]; } cov[w]=0; } } inline void up(int w){ mx[w]=max(mx[lc[w]],mx[rc[w]]); } int build(int L,int R){ int u=++p; if(L==R){ mx[u]=v0[idr[L]]; return u; } int M=L+R>>1; lc[u]=build(L,M); rc[u]=build(M+1,R); up(u); return u; } void getmax(int w,int L,int R){ if(l<=L&&R<=r){ ans=max(ans,mx[w]); return; } dwn(w); int M=L+R>>1; if(l<=M)getmax(lc[w],L,M); if(r>M)getmax(rc[w],M+1,R); } void chg(int w,int L,int R){ if(l<=L&&R<=r){ a[w]=0; cov[w]=1; mx[w]=ans; return; } dwn(w); int M=L+R>>1; if(l<=M)chg(lc[w],L,M); if(r>M)chg(rc[w],M+1,R); up(w); } void inc(int w,int L,int R){ if(l<=L&&R<=r){ if(!cov[w])a[w]+=ans; mx[w]+=ans; return; } dwn(w); int M=L+R>>1; if(l<=M)inc(lc[w],L,M); if(r>M)inc(rc[w],M+1,R); up(w); } void f1(int w,int pa){ fa[w]=pa; dep[w]=dep[pa]+1; sz[w]=1; for(int i=e0[w];i;i=enx[i]){ int u=es[i]; if(u==pa)continue; v0[u]=ev[i]; f1(u,w); sz[w]+=sz[u]; if(sz[u]>sz[son[w]])son[w]=u; } } void f2(int w,int tp){ top[w]=tp; idr[id[w]=idp++]=w; if(son[w])f2(son[w],tp); for(int i=e0[w];i;i=enx[i]){ int u=es[i]; if(u!=fa[w]&&u!=son[w])f2(u,u); } } void qmax(int x,int y){ ans=0; int a=top[x],b=top[y],c; while(a!=b){ if(dep[a]<dep[b])c=a,a=b,b=c,c=x,x=y,y=c; l=id[a];r=id[x]; getmax(1,1,n); x=fa[a];a=top[x]; } if(dep[x]<dep[y])l=id[x]+1,r=id[y]; else l=id[y]+1,r=id[x]; if(l<=r)getmax(1,1,n); printf("%d\n",ans); } void add(int x,int y){ int a=top[x],b=top[y],c; while(a!=b){ if(dep[a]<dep[b])c=a,a=b,b=c,c=x,x=y,y=c; l=id[a];r=id[x]; inc(1,1,n); x=fa[a];a=top[x]; } if(dep[x]<dep[y])l=id[x]+1,r=id[y]; else l=id[y]+1,r=id[x]; if(l<=r)inc(1,1,n); } void change(int x,int y){ int a=top[x],b=top[y],c; while(a!=b){ if(dep[a]<dep[b])c=a,a=b,b=c,c=x,x=y,y=c; l=id[a];r=id[x]; chg(1,1,n); x=fa[a];a=top[x]; } if(dep[x]<dep[y])l=id[x]+1,r=id[y]; else l=id[y]+1,r=id[x]; if(l<=r)chg(1,1,n); } int main(){ fread(buf,1,10000000,stdin); n=input(); for(int i=1;i<n;i++){ int a=input(),b=input(),c=input(); es[ep]=b;enx[ep]=e0[a];ev[ep]=c;e0[a]=ep++; es[ep]=a;enx[ep]=e0[b];ev[ep]=c;e0[b]=ep++; ei[i][0]=a; ei[i][1]=b; } f1(1,0);f2(1,1);build(1,n); while(1){ int op=getop(); if(op==‘t‘)break; if(op==‘a‘){ int a=input(),b=input(); qmax(a,b); }else if(op==‘h‘){ int a=input(),b=input(); l=r=(dep[ei[a][0]]>dep[ei[a][1]]?id[ei[a][0]]:id[ei[a][1]]); ans=b; chg(1,1,n); }else if(op==‘d‘){ int a=input(),b=input(),c=input(); ans=c; add(a,b); }else{ int a=input(),b=input(),c=input(); ans=c; change(a,b); } } return 0; }
时间: 2024-10-11 17:05:47