WA on #1,#12-20
貌似是加边删边写炸(?)
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define int long long
const int N=524288,mod=51061;
struct linkcuttree{
struct lcrnode{
int die,ez[2],sz;
ll add,mul;
ll val,sum;
bool rev;
}t[N];
#define ls(p) t[p].ez[0]
#define rs(p) t[p].ez[1]
inline void pushup(int p){
t[p].sz=t[ls(p)].sz+t[rs(p)].sz+1;
t[p].sum=(t[ls(p)].sum+t[rs(p)].sum+t[p].val)%mod;
}
void mt(int pos,ll val){
t[pos].sum*=val;t[pos].val*=val;
t[pos].add*=val;t[pos].mul*=val;
t[pos].sum%=mod;t[pos].val%=mod;
t[pos].add%=mod;t[pos].mul%=mod;
}
void add(int pos,ll val){
t[pos].sum+=val*t[pos].sz;
t[pos].add+=val,t[pos].val+=val;
t[pos].add%=mod,t[pos].val%=mod;
t[pos].sum%=mod;
}
inline void pushdown(int p){
if(t[p].mul!=1){
mt(ls(p),t[p].mul);
mt(rs(p),t[p].mul);
t[p].mul=1;
}
if(t[p].add){
add(ls(p),t[p].add);
add(rs(p),t[p].add);
t[p].add=0;
}
if(t[p].rev){
t[ls(p)].rev^=1;
t[rs(p)].rev^=1;
t[p].rev=0;
swap(ls(p),rs(p));
}
}
inline bool get(int p){return rs(t[p].die)==p;}
inline bool isroot(int x){
return ls(t[x].die)!=x&&rs(t[x].die)!=x;
}
inline void update(int x){
if(!isroot(x))update(t[x].die);
pushdown(x);
}
void rotate(int x){
int die=t[x].die,ye=t[die].die;
bool mk=get(x);
if(!isroot(die))t[ye].ez[rs(ye)==die]=x;
t[die].ez[mk]=t[x].ez[!mk];
t[t[x].ez[!mk]].die=die;
t[x].ez[!mk]=die;
t[die].die=x,t[x].die=ye;
pushup(die),pushup(x);
}
void splay(int x){
update(x);
for(int die=t[x].die;die=t[x].die,!isroot(x);rotate(x)){
if(!isroot(die))rotate(get(die)==get(x)?die:x);
}
}
void access(int x){
int p=0;
for(;x;p=x,x=t[p].die){
splay(x);
t[x].ez[1]=p;
pushup(x);
}
}
void makeroot(int p){
access(p);
splay(p);
t[p].rev^=1;
pushdown(p);
}
int find(int p){
access(p);
splay(p);
pushdown(p);
while(ls(p))p=ls(p),pushdown(p);
return p;
}
void link(int x,int y){
makeroot(x);
if(find(y)!=x){
t[x].die=y;
}
}
void split(int x,int y){
makeroot(x);
access(y);
splay(y);
}
void cut(int x,int y){
makeroot(x);
if(find(y)==x&&t[y].die==x&&!ls(y))t[y].die=t[x].ez[1]=0;
}
}lct;
int n,q;
_Atomic_word main(){
//freopen("P1501_1.in","r",stdin);
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n>>q;
for(int i=1;i<=n;i++)lct.t[i].mul=lct.t[i].sz=lct.t[i].val=1;
for(int i=1;i<n;i++){
int x,y;
cin>>x>>y;
lct.link(x,y);
}
for(int i=1;i<=q;i++){
char op;cin>>op;
if(op=='+'){
int u,v,c;cin>>u>>v>>c;
lct.split(u,v);
lct.add(v,c);
}
else if(op=='-'){
int u,v,x,y;cin>>u>>v>>x>>y;
/*if(lct.find(u)==lct.find(v))*/lct.cut(u,v);
/*if(lct.find(x)!=lct.find(y))*/lct.link(x,y);
}
else if(op=='*'){
int u,v,c;cin>>u>>v>>c;
lct.split(u,v);lct.mt(v,c);
}
else {
int x,y;cin>>x>>y;
lct.split(x,y);
cout<<lct.t[y].sum<<'\n';
}
}
return EXIT_SUCCESS;
}
/*十年OI一场空,不开LL见祖宗。
似是神牛成才处,实为蒟蒻黄泉路。
黄题有恨无正解,码力不若小学生。
今生无奈入OI,来世不做信竞人。 */