自闭了, 真的搞不懂split之后cut和Link的操作, 但感觉不是那个问题
#include <bits/stdc++.h>
#define mod 51061
#define int long long
#define maxn 200005
using namespace std;
int ch[maxn][2], ans[maxn], sz[maxn], taga[maxn], tagm[maxn], rev[maxn], val[maxn], fa[maxn], n, q;
bool get(int x) {
return x == ch[fa[x]][1];
}
bool isroot(int x) {
return (x != ch[fa[x]][0] && x != ch[fa[x]][1]);
}
void pushup(int x) {
ans[x] = ans[ch[x][0]] + ans[ch[x][1]] + val[x];
ans[x] %= mod;
sz[x] = sz[ch[x][0]] + sz[ch[x][1]] + 1;
}
void add(int x, int k) {
ans[x] += k * sz[x], taga[x] += k, val[x] += k;
ans[x] %= mod, taga[x] %= mod, val[x] %= mod;
}
void mul(int x, int k) {
ans[x] *= k, taga[x] *= k, tagm[x] *= k, val[x] *= k;
ans[x] %= mod, taga[x] %= mod, tagm[x] %= mod, val[x] %= mod;
}
void rotate(int x) {
int y = fa[x], z = fa[y], chk = get(x);
if(!isroot(y)) ch[z][get(y)] = x;
ch[y][chk] = ch[x][chk ^ 1], fa[ch[x][chk ^ 1]] = y;
ch[x][chk ^ 1] = y;
fa[y] = x, fa[x] = z;
pushup(y), pushup(x);
}
void pushv(int p) {
swap(ch[p][0], ch[p][1]);
rev[p] ^= 1;
}
void pushdown(int x) {
if(rev[x]) {
if(ch[x][0]) pushv(ch[x][0]);
if(ch[x][1]) pushv(ch[x][1]);
rev[x] = 0;
}
if(taga[x]) {
if(ch[x][0]) add(ch[x][0], taga[x]);
if(ch[x][1]) add(ch[x][1], taga[x]);
taga[x] = 0;
}
if(tagm[x] != 1) {
if(ch[x][0]) mul(ch[x][0], tagm[x]);
if(ch[x][1]) mul(ch[x][1], tagm[x]);
tagm[x] = 1;
}
}
void update(int x) {
if(fa[x]) update(fa[x]);
pushdown(x);
}
void splay(int x) {
update(x);
for(int f = 0;f = fa[x], !isroot(x);rotate(x)) {
if(!isroot(f)) rotate(get(x) == get(f) ? f : x);
}
}
void access(int x) {
for(int f = 0;x;x = fa[f = x]) {
splay(x), ch[x][1] = f, pushup(x);
}
}
void makeroot(int x) {
access(x), splay(x), pushv(x);
}
void split(int x, int y) {
makeroot(x), access(y), splay(y);
}
int find(int p) {
access(p), splay(p);
while(ch[p][0]) p = ch[p][0];
splay(p);
return p;
}
void link(int x, int y) {
split(x, y);
/*if(find(x) != find(y)) */fa[x] = y;
}
void cut(int x, int y) {
split(x, y);
// if(find(y) == find(x) && fa[y] == x && !ch[x][0]) {
fa[x] = ch[y][0] = 0;
// pushup(x);
// }
}
signed main() {
// freopen("q.in", "r", stdin);
// freopen("w.out", "w", stdout);
scanf("%lld%lld", &n, &q);
for(int i = 1;i <= n;i++) tagm[i] = val[i] = sz[i] = 1;
for(int i = 1;i <= n - 1;i++) {
int u, v;
scanf("%lld%lld", &u, &v);
link(u, v);
}
for(int i = 1;i <= q;i++) {
char p;
int x, y, z, k;
cin >> p;scanf("%lld%lld", &x, &y);
if(p == '+') {
scanf("%lld", &z);
split(x, y);
add(y, z);
// cout << ans[y] << endl;
}
else if(p == '-') {
scanf("%lld%lld", &k, &z);
cut(x, y);
link(z, k);
}
else if(p == '*') {
scanf("%lld", &z);
split(x, y);
mul(y, z);
}
else {
split(x, y);
printf("%lld\n", ans[y]);
}
}
}