RE + WA 0pts 求助
查看原帖
RE + WA 0pts 求助
558336
root357楼主2023/3/11 13:36

如题,目前像是标记更新不完全,并且某个函数疑似有越界(或爆栈)问题。 代码如下。

#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;
}
2023/3/11 13:36
加载中...