LCT?不存在的!
。。。。
注意此处kr=val,val=sum。pushdown的时候把这些东西一起更新了会方便很多。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxv 100050 #define mod 51061 #define int unsigned using namespace std; int n,q,u,v,c,tree[maxv][3],rev[maxv],val[maxv],kr[maxv]; int tag1[maxv],tag2[maxv],fath[maxv],st[maxv],top=0,size[maxv]; char s[4]; int read() { int ch=getchar(),data=0; while (ch<'0' || ch>'9') ch=getchar(); while (ch>='0' && ch<='9') { data=data*10+ch-'0'; ch=getchar(); } return data; } bool isroot(int x) {return tree[fath[x]][1]!=x && tree[fath[x]][2]!=x;} void pushup(int x) {val[x]=(val[tree[x][1]]+val[tree[x][2]]+kr[x])%mod;size[x]=size[tree[x][1]]+size[tree[x][2]]+1;} void pushdown(int x) { if (rev[x]) {swap(tree[x][1],tree[x][2]);rev[tree[x][1]]^=1;rev[tree[x][2]]^=1;rev[x]=0;} if (tag2[x]-1) { kr[tree[x][1]]*=tag2[x];kr[tree[x][1]]%=mod;tag1[tree[x][1]]*=tag2[x];tag1[tree[x][1]]%=mod; kr[tree[x][2]]*=tag2[x];kr[tree[x][2]]%=mod;tag1[tree[x][2]]*=tag2[x];tag1[tree[x][2]]%=mod; tag2[tree[x][1]]*=tag2[x];tag2[tree[x][1]]%=mod;tag2[tree[x][2]]*=tag2[x];tag2[tree[x][2]]%=mod; val[tree[x][1]]*=tag2[x];val[tree[x][1]]%=mod;val[tree[x][2]]*=tag2[x];val[tree[x][2]]%=mod; tag2[x]=1; } if (tag1[x]) { kr[tree[x][1]]+=tag1[x];kr[tree[x][1]]%=mod;tag1[tree[x][1]]+=tag1[x];tag1[tree[x][1]]%=mod; kr[tree[x][2]]+=tag1[x];kr[tree[x][2]]%=mod;tag1[tree[x][2]]+=tag1[x];tag1[tree[x][2]]%=mod; val[tree[x][1]]+=size[tree[x][1]]*tag1[x]%mod;val[tree[x][1]]%=mod; val[tree[x][2]]+=size[tree[x][2]]*tag1[x]%mod;val[tree[x][2]]%=mod; tag1[x]=0; } } void rotate(int x) { int y=fath[x],z=fath[y],l,r; if (tree[y][1]==x) l=1;else l=2;r=3-l; if (!isroot(y)) { if (tree[z][1]==y) tree[z][1]=x; else tree[z][2]=x; } fath[x]=z;fath[y]=x;fath[tree[x][r]]=y; tree[y][l]=tree[x][r];tree[x][r]=y; pushup(y);pushup(x); } void splay(int x) { int t=x;top=0; while (!isroot(t)) {st[++top]=t;t=fath[t];}st[++top]=t; for (int i=top;i>=1;i--) pushdown(st[i]); while (!isroot(x)) { int y=fath[x],z=fath[y]; if (!isroot(y)) { if ((tree[z][1]==y)^(tree[y][1]==x)) rotate(x); else rotate(y); } rotate(x); } } void access(int x) { int regis=0; while (x) { splay(x); tree[x][2]=regis; regis=x;pushup(x); x=fath[x]; } } void makeroot(int x) {access(x);splay(x);rev[x]^=1;} void cut(int u,int v) {makeroot(u);access(v);splay(v);tree[v][1]=fath[u]=0;} void link(int u,int v) {makeroot(u);fath[u]=v;splay(u);} void modify(int u,int v,int c,int type) { makeroot(u); access(v); splay(v); if (type==1) {tag1[v]+=c;tag1[v]%=mod;kr[v]+=c;kr[v]%=mod;pushup(v);} else {tag1[v]*=c;tag1[v]%=mod;tag2[v]*=c;tag2[v]%=mod;kr[v]*=c;kr[v]%=mod;pushup(v);} } int ask(int u,int v) { makeroot(u); access(v); splay(v); return val[v]%mod; } main() { n=read();q=read(); for (int i=1;i<=n;i++) val[i]=tag2[i]=kr[i]=1; for (int i=1;i<=n-1;i++) { u=read();v=read(); link(u,v); } for (int i=1;i<=q;i++) { scanf("%s",s); if (s[0]=='+') {u=read();v=read();c=read();modify(u,v,c,1);} else if (s[0]=='*') {u=read();v=read();c=read();modify(u,v,c,2);} else if (s[0]=='-') { u=read();v=read();cut(u,v); u=read();v=read();link(u,v); } else {u=read();v=read();printf("%d\n",ask(u,v));} } return 0; }