不知道为什么我的lct巨慢
没加zigzag30004ms,加了zigzag19000ms。。。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define mod 51061
#define maxn 100100
#define inf (1<<30)
using namespace std;
typedef unsigned int ll;
ll sum[maxn],add[maxn],cheng[maxn],fa[maxn],tag[maxn];
ll rev[maxn],ch[maxn][2],key[maxn],size[maxn],n,m;
void updatecheng(int u,int c){
if(add[u]!=inf)add[u]=(add[u]*c)%mod;
cheng[u]=(cheng[u]==inf?c:cheng[u]*c)%mod;
sum[u]=sum[u]*c%mod;
key[u]=key[u]*c%mod;
}
void updateadd(int u,int c){
add[u]=(add[u]==inf?c:add[u]+c)%mod,
sum[u]=(sum[u]+c*size[u])%mod,
key[u]=(key[u]+c)%mod;
}
void pushdown(int x){
if(tag[x]){
tag[x]=0;
if(ch[x][0])tag[ch[x][0]]^=1;
if(ch[x][1])tag[ch[x][1]]^=1;
swap(ch[x][0],ch[x][1]);
}
if(cheng[x]!=inf){
if(ch[x][0])updatecheng(ch[x][0],cheng[x]);
if(ch[x][1])updatecheng(ch[x][1],cheng[x]);
cheng[x]=inf;
}
if(add[x]!=inf){
if(ch[x][0])updateadd(ch[x][0],add[x]);
if(ch[x][1])updateadd(ch[x][1],add[x]);
add[x]=inf;
}
}
void update(int x){
if(!x)return ;
sum[x]=(sum[ch[x][0]]+sum[ch[x][1]]+key[x])%mod;
size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
}
bool notroot(int x){
return (ch[fa[x]][0]==x||ch[fa[x]][1]==x);
}
void rotate(int p){
int q=fa[p],y=fa[q],k=(ch[q][1]==p);
if(y&¬root(q))ch[y][ch[y][1]==q]=p;
fa[ch[q][k]=ch[p][k^1]]=q;
fa[ch[p][k^1]=q]=p;
fa[p]=y;
update(q),update(p);
}
void splay(int x){
int y=0;
while(notroot(x)){
if(notroot(y=fa[x]))pushdown(fa[y]);
pushdown(y);pushdown(x);
if(notroot(y)){
if((ch[fa[x]][1]==x)^(ch[fa[y]][1]==y))rotate(x);
else rotate(y);
}
rotate(x);
}
pushdown(x);
update(x);
}
void access(int x){
for(int y=0;x;y=x,x=fa[x]){
splay(x);
ch[x][1]=y,fa[y]=x;
update(x);
}
}
void rever(int u){
access(u),splay(u);
tag[u]^=1,pushdown(u);
}
void cut(int u,int v){
rever(u);access(v);splay(v);
fa[u]=ch[v][0]=0;
}
void link(int u,int v){
rever(u);access(v);splay(v);
fa[v]=u,ch[u][0]=v;
}
int main(){
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)size[i]=key[i]=sum[i]=1,cheng[i]=add[i]=inf;
for(int i=1,u,v;i<n;++i)
scanf("%d%d",&u,&v),link(u,v);
for(int i=1;i<=m;++i){
char op[2];ll u,v,c;
// for(int i=1;i<=n;++i)printf("[%d]",key[i]);
scanf("%s%d%d",op,&u,&v);
if(op[0]=='+'){
scanf("%d",&c);
rever(u);access(v);splay(v);
if(add[v]!=inf)(add[v]+=c)%=mod;
else add[v]=c%mod;
sum[v]=(size[v]*c+sum[v])%mod;
key[v]=(c+key[v])%mod;
} else if(op[0]=='-'){
int u2,v2;scanf("%d%d",&u2,&v2);
cut(u,v),link(u2,v2);
} else if(op[0]=='*'){
scanf("%d",&c);
rever(u);access(v);splay(v);
if(cheng[v]!=inf)cheng[v]=c*cheng[v]%mod;
else cheng[v]=c%mod;
if(add[v]!=inf)add[v]=c*add[v]%mod;
sum[v]=(sum[v]*c)%mod;
key[v]=(key[v]*c)%mod;
} else {
rever(u);access(v);splay(v);
printf("%d\n",sum[v]);
}
}
}