给出一棵树,请你支持:
1)删边。
2)加边。
3)路径点权+c。
4)路径点权乘c。
5)询问路径点权和。
答案对51061取模。
#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+10;
const int mod=51061;
typedef long long ll;
ll ch[maxn][2],fa[maxn],sz[maxn],val[maxn],sum[maxn],rev[maxn];
ll add[maxn],mul[maxn];
void clear (int x) {
ch[x][0]=ch[x][1]=fa[x]=sz[x]=val[x]=sum[x]=rev[x]=add[x]=0;
mul[x]=1;
}
int get (int x) {
return ch[fa[x]][1]==x?1:0;
}
int isRoot (int x) {
clear(0);
return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
}
void pushup (int x) {
clear(0);
sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;sz[x]%=mod;
sum[x]=(sum[ch[x][0]]+sum[ch[x][1]]+val[x])%mod;
}
void pushdown (int x) {
clear(0);
if (mul[x]!=1) {
if (ch[x][0]) {
mul[ch[x][0]]=(mul[ch[x][0]]*mul[x])%mod;
val[ch[x][0]]=(val[ch[x][0]]*mul[x])%mod;
sum[ch[x][0]]=(sum[ch[x][0]]*mul[x])%mod;
add[ch[x][0]]=(add[ch[x][0]]*mul[x])%mod;
}
if (ch[x][1]) {
mul[ch[x][1]]=(mul[ch[x][1]]*mul[x])%mod;
val[ch[x][1]]=(val[ch[x][1]]*mul[x])%mod;
sum[ch[x][1]]=(sum[ch[x][1]]*mul[x])%mod;
add[ch[x][1]]=(add[ch[x][1]]*mul[x])%mod;
}
mul[x]=1;
}
if (add[x]) {
if (ch[x][0]) {
add[ch[x][0]]=(add[ch[x][0]]+add[x])%mod;
val[ch[x][0]]=(val[ch[x][0]]+add[x])%mod;
sum[ch[x][0]]=(sum[ch[x][0]]+add[x]*sz[ch[x][0]]%mod)%mod;
}
if (ch[x][1]) {
add[ch[x][1]]=(add[ch[x][1]]+add[x])%mod;
val[ch[x][1]]=(val[ch[x][1]]+add[x])%mod;
sum[ch[x][1]]=(sum[ch[x][1]]+add[x]*sz[ch[x][1]]%mod)%mod;
}
add[x]=0;
}
if (rev[x]) {
if (ch[x][0]) {
rev[ch[x][0]]^=1;
swap(ch[ch[x][0]][0],ch[ch[x][0]][1]);
}
if (ch[x][1]) {
rev[ch[x][1]]^=1;
swap(ch[ch[x][1]][0],ch[ch[x][1]][1]);
}
rev[x]=0;
}
}
void update (int x) {
if (!isRoot(x)) update(fa[x]);
pushdown(x);
}
void rotate (int x) {
int y=fa[x],z=fa[y],chx=get(x),chy=get(y);
fa[x]=z;
if (!isRoot(y)) ch[z][chy]=x;
ch[y][chx]=ch[x][chx^1];
fa[ch[x][chx^1]]=y;
ch[x][chx^1]=y;
fa[y]=x;
pushup(y);
pushup(x);
pushup(z);
}
void splay (int x) {
update(x);
for (int f=fa[x];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;f=x,x=fa[x]) {
splay(x);
ch[x][1]=f;
pushup(x);
}
}
void makeRoot (int x) {
access(x);
splay(x);
swap(ch[x][0],ch[x][1]);
rev[x]^=1;
}
int find (int x) {
access(x);
splay(x);
while (ch[x][0]) x=ch[x][0];
splay(x);
return x;
}
int n,q;
int main () {
scanf("%d%d",&n,&q);
for (int i=1;i<=n;i++) val[i]=1,pushup(i);
for (int i=1;i<n;i++) {
int u,v;
scanf("%d%d",&u,&v);
if (find(u)!=find(v)) {
makeRoot(u);
fa[u]=v;
}
}
while (q--) {
char op;
int u,v;
cin>>op>>u>>v;
if (op=='+') {
ll c;
scanf("%lld",&c);
makeRoot(u);
access(v);
splay(v);
val[v]=(val[v]+c)%mod;
sum[v]=(sum[v]+sz[v]*c%mod)%mod;
add[v]=(add[v]+c)%mod;
}
else if (op=='-') {
makeRoot(u);
access(v);
splay(v);
if (ch[v][0]==u&&!ch[u][1]) ch[v][0]=fa[u]=0;
scanf("%d%d",&u,&v);
if (find(u)!=find(v)) {
makeRoot(u);fa[u]=v;
}
}
else if (op=='*') {
ll c;
scanf("%lld",&c);
c%=mod;
makeRoot(u);
access(v);
splay(v);
val[v]=(val[v]*c)%mod;
sum[v]=(sum[v]*c)%mod;
mul[v]=(mul[v]*c)%mod;
//add[v]=(add[v]*c)%mod;
}
else if (op=='/') {
makeRoot(u);
access(v);
splay(v);
sum[v]%=mod;
printf("%lld
",sum[v]);
}
}
}