如题,目前像是标记更新不完全,并且某个函数疑似有越界(或爆栈)问题。 代码如下。
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 100010;
const int Mod = 51061;
int stk[N] = {0};
int fa[N] = {0}, son[N][2] = {0};
int rev[N] = {0}, tagAdd[N] = {0}, tagMul[N] = {0}, siz[N] = {0}, sum[N] = {0}, nval[N] = {0};
template <typename T > void swap (T a, T b) {
T t = a;
a = b;
b = t;
}
bool nroot (int x) {
return son[fa[x]][0] == x || son[fa[x]][1] == x;
}
void pushrev (int x) {
swap (son[x][0], son[x][1]);
rev[x] ^= 1;
}
void pushAdd (int x, int v) {
sum[x] = (sum[x] + 1ll * siz[x] * v % Mod) % Mod;
nval[x] = (nval[x] + v) % Mod;
tagAdd[x] = (tagAdd[x] + v) % Mod;
}
void pushMul (int x, int v) {
sum[x] = 1ll * sum[x] * v % Mod;
nval[x] = 1ll * nval[x] * v % Mod;
tagAdd[x] = 1ll * tagAdd[x] * v % Mod;
tagMul[x] = 1ll * tagMul[x] * v % Mod;
}
void pushup (int x) {
sum[x] = (sum[son[x][0]] + sum[son[x][1]] + nval[x]) % Mod;
siz[x] = siz[son[x][0]] + siz[son[x][1]] + 1;
}
void pushdown (int x) {
if (tagMul[x] != 1) {
if (son[x][0] != 0) {
pushMul (son[x][0], tagMul[x]);
}
if (son[x][1] != 0) {
pushMul (son[x][1], tagMul[x]);
}
}
if (tagAdd[x] != 0) {
if (son[x][0] != 0) {
pushAdd (son[x][0], tagAdd[x]);
}
if (son[x][1] != 0) {
pushAdd (son[x][1], tagAdd[x]);
}
}
if (rev[x] != 0) {
if (son[x][0] != 0) {
pushrev (son[x][0]);
}
if (son[x][1] != 0) {
pushrev (son[x][1]);
}
}
tagAdd[x] = 0, tagMul[x] = 1, rev[x] = 0;
}
void Rotate (int x) {
int y = fa[x], z = fa[y], k = son[y][1] == x, s = son[x][!k];
if (nroot (y)) {
son[z][son[z][1] == y] = x;
}
son[x][!k] = y, son[y][k] = s;
if (s != 0) {
fa[s] = y;
}
fa[y] = x, fa[x] = z;
pushup (y);
}
void Splay (int x) {
int y = x, top = 0;
stk[++ top] = y;
while (nroot (y)) {
stk[++ top] = y = fa[y];
}
while (top != 0) {
pushdown (stk[top --]);
}
while (nroot (x)) {
int y = fa[x], z = fa[y];
if (nroot (y)) {
Rotate ((son[y][0] == x) ^ (son[z][0] == y) ? x : y);
}
Rotate (x);
}
pushup (x);
}
void Access (int x) {
for (int y = 0; x; x = fa[y = x]) {
Splay (x);
son[x][1] = y;
pushup (x);
}
}
void makeroot (int x) {
Access (x);
Splay (x);
pushrev (x);
}
void Split (int x, int y) {
makeroot (x);
Access (y);
Splay (y);
}
void link (int x, int y) {
makeroot (x);
fa[x] = y;
}
void cut (int x, int y) {
Split (x, y);
fa[x] = son[y][0] = 0;
}
void print (int x) {
if (x == 0) {
return;
}
print (son[x][0]);
printf("%d ", x);
print (son[x][1]);
}
int main () {
freopen("tree.in", "r", stdin);
freopen("tree.out", "w", stdout);
int n, q;
scanf("%d%d", &n, &q);
for (int i = 1; i <= n; i ++) {
nval[i] = siz[i] = tagMul[i] = 1;
}
for (int i = 1; i < n; i ++) {
int u, v;
scanf("%d%d", &u, &v);
link (u, v);
}
while (q --) {
char opt[3];
scanf("%s", opt + 1);
if (opt[1] == '+') {
int u, v, c;
scanf("%d%d%d", &u, &v, &c);
Split (u, v);
pushAdd (v, c);
}
else if (opt[1] == '-') {
int u, v, x, y;
scanf("%d%d%d%d", &u, &v, &x, &y);
cut (u, v);
link (x, y);
}
else if (opt[1] == '*') {
int u, v, c;
scanf("%d%d%d", &u, &v, &c);
Split (u, v);
pushMul (v, c);
}
else if (opt[1] == '/') {
int u, v;
scanf("%d%d", &u, &v);
Split (u, v);
printf("%d\n", sum[v]);
}
}
return 0;
}