1. 程式人生 > >LCT(維護加乘標記)--luogu P1501 [國家集訓隊]Tree II

LCT(維護加乘標記)--luogu P1501 [國家集訓隊]Tree II

傳送門

就是鏈上維護加和乘的標記,先乘後加
沒開long long wa到懷疑人生祭

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define N 100005
#define ls ch[x][0]
#define rs ch[x][1]
#define fa f[x]
#define LL long long
#define int LL
using namespace std;

inline
int rd(){ int x=0,f=1;char c=' '; while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar(); while(c<='9' && c>='0') x=x*10+c-'0',c=getchar(); return x*f; } int n,q; int f[N],ch[N][2],rev[N],sum[N],tag1[N],tag2[N],val[N],siz[N]; const int mod=51061; inline int get(int x){return
ch[fa][1]==x;} inline int isrt(int x){return ch[fa][0]!=x && ch[fa][1]!=x;} inline void update(int x){sum[x]=(sum[ls]+sum[rs]+val[x])%mod;siz[x]=siz[ls]+siz[rs]+1;} inline void rever(int x){rev[x]^=1;swap(ls,rs);} inline void pushdown(int x){ if(rev[x]){ if(ls) rever(ls); if(rs)
rever(rs); rev[x]=0; } if(tag2[x]!=1){ int t=tag2[x]; tag2[x]=1; if(ls){ val[ls]=1LL*val[ls]*t%mod; tag1[ls]=1LL*tag1[ls]*t%mod; tag2[ls]=1LL*tag2[ls]*t%mod; sum[ls]=1LL*sum[ls]*t%mod; } if(rs){ val[rs]=1LL*val[rs]*t%mod; tag1[rs]=1LL*tag1[rs]*t%mod; tag2[rs]=1LL*tag2[rs]*t%mod; sum[rs]=1LL*sum[rs]*t%mod; } } if(tag1[x]!=0){ int t=tag1[x]; tag1[x]=0; if(ls){ (val[ls]+=t)%=mod; (tag1[ls]+=t)%=mod; (sum[ls]+=1LL*t*siz[ls]%mod)%=mod; } if(rs){ (val[rs]+=t)%=mod; (tag1[rs]+=t)%=mod; (sum[rs]+=1LL*t*siz[rs]%mod)%=mod; } } // update(ls); update(rs); } void pushup(int x){if(!isrt(x)) pushup(fa);pushdown(x);} inline void rotate(int x){ int old=f[x],oldf=f[old],wh=get(x); if(!isrt(old)) ch[oldf][get(old)]=x; ch[old][wh]=ch[x][wh^1]; f[ch[x][wh^1]]=old; ch[x][wh^1]=old; f[x]=oldf; f[old]=x; update(old); update(x); } inline void splay(int x){ pushup(x); for(;!isrt(x);rotate(x)) if(!isrt(fa)) rotate(get(x)==get(fa)?fa:x); } inline void access(int x){ for(int y=0;x;y=x,x=fa) splay(x),rs=y,update(x); } inline void makeroot(int x){ access(x); splay(x); rever(x); } inline int findroot(int x){ access(x); splay(x); while(ls) pushdown(x),x=ls; return x; } inline void split(int x,int y){ makeroot(x); access(y); splay(y); } inline void link(int x,int y){ if(findroot(x)==findroot(y)) return; makeroot(x); f[x]=y; } inline void cut(int x,int y){ if(findroot(x)!=findroot(y)) return; split(x,y); if(ch[y][0]==x && !ch[x][1]) f[x]=ch[y][0]=0,update(y); } char s[10]; int x,y,z,p; signed main(){ n=rd(); q=rd(); for(int i=1;i<=n;i++) val[i]=1,tag2[i]=1; for(int i=1;i<n;i++){ x=rd(),y=rd(); link(x,y); } while(q--){ scanf("%s",s); if(s[0]=='+'){ x=rd(),y=rd(),z=rd(); split(x,y); (sum[y]+=1LL*siz[y]*z%mod)%=mod; (val[y]+=z%mod)%=mod; (tag1[y]+=z)%=mod; } if(s[0]=='-'){ x=rd(),y=rd(),z=rd(),p=rd(); cut(x,y); link(z,p); } if(s[0]=='*'){ x=rd(),y=rd(),z=rd(); split(x,y); val[y]=1LL*val[y]*z%mod; sum[y]=1LL*sum[y]*z%mod; tag1[y]=1LL*tag1[y]*z%mod; tag2[y]=1LL*tag2[y]*z%mod; } if(s[0]=='/'){ x=rd(),y=rd(); split(x,y); printf("%lld\n",sum[y]%mod); } } return 0; }