【题目分析】
又一道LCT的题目,LCT只能维护链上的信息。
【代码】
#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <set> #include <map> #include <string> #include <algorithm> #include <vector> #include <iostream> #include <queue> using namespace std; #define maxn 1000005 #define inf (0x3f3f3f3f) #define mod 51061 unsigned int read() { unsigned int x=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();} while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();} return x*f; } unsigned int ch[maxn][2],fa[maxn],add[maxn],mul[maxn],num[maxn],sum[maxn]; unsigned int n,m,siz[maxn],rev[maxn],sta[maxn],top=0; void update(unsigned int x) { siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1; sum[x]=(sum[ch[x][0]]+sum[ch[x][1]]+num[x])%mod; } void solve(unsigned int x,unsigned int ad,unsigned int ml) { if (!x) return ; add[x]=(add[x]*ml+ad)%mod; mul[x]=(mul[x]*ml)%mod; sum[x]=(sum[x]*ml+siz[x]*ad)%mod; num[x]=(num[x]*ml+ad)%mod; } void pushdown(unsigned int x) { if (rev[x]) { rev[x]^=1; rev[ch[x][0]]^=1; rev[ch[x][1]]^=1; swap(ch[x][0],ch[x][1]); } solve(ch[x][0],add[x],mul[x]); solve(ch[x][1],add[x],mul[x]); mul[x]=1; add[x]=0; } bool isroot(unsigned int x) { return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x; } void rot(unsigned int x) { unsigned int y=fa[x],z=fa[y],l,r; if (ch[y][0]==x) l=0; else l=1; r=l^1; if (!isroot(y)) { if (ch[z][0]==y) ch[z][0]=x; else ch[z][1]=x; } fa[x]=z; fa[y]=x; fa[ch[x][r]]=y; ch[y][l]=ch[x][r]; ch[x][r]=y; update(y); update(x); } void splay(unsigned int x) { unsigned int top=0; sta[top++]=x; for (int i=x;!isroot(i);i=fa[i]) sta[top++]=fa[i]; while (top--) pushdown(sta[top]); while (!isroot(x)) { unsigned int y=fa[x],z=fa[y]; if (!isroot(y)) { if (ch[z][0]==y^ch[y][0]==x) rot(x); else rot(y); } rot(x); } } void access(unsigned int x) { for (int t=0;x;t=x,x=fa[x]) splay(x),ch[x][1]=t,update(x); } void makeroot(unsigned int x) { access(x); splay(x); rev[x]^=1; } unsigned int find(unsigned int x) { access(x); splay(x); while (ch[x][0]) x=ch[x][0]; return x; } void link(unsigned int x,unsigned int y) { makeroot(x); fa[x]=y; } void cut(unsigned int x,unsigned int y) { makeroot(x); access(y); splay(y); ch[y][0]=fa[x]=0; } int main() { n=read();m=read(); for (unsigned int i=1;i<=n;++i) num[i]=1,update(i); char opt[10]; for (unsigned int i=1;i<n;++i) link(read(),read()); while (m--) { scanf("%s",opt); unsigned int x,y,z; switch (opt[0]) { case '+': x=read(); y=read(); z=read(); makeroot(x); access(y); splay(y); solve(y,z,1); break; case '-': cut(read(),read()); link(read(),read()); break; case '*': x=read();y=read();z=read(); makeroot(x); access(y); splay(y); solve(y,0,z); break; case '/': x=read();y=read(); makeroot(x); access(y); splay(y); printf("%u\n",sum[y]); break; } } }