求助树剖,WA 了,只有 10 分
查看原帖
求助树剖,WA 了,只有 10 分
394729
Weight_of_the_Soul楼主2022/8/20 21:10
#include <cstdio>
#include <algorithm>
#include <cstring>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;

int rd() {
    int x = 0, w = 1;
    char c = getchar();

    while(c < '0' || c > '9') {
        if(c == '-') w = -1;
        c = getchar();
    }

    while(c >= '0' && c <= '9') {
        x = x * 10 + (c - '0');
        c = getchar();
    }

    return x * w;
}

const int N = 1e5 + 5, M = 1e5 + 5;
int n, m, q;
int son[N], siz[N], fa[N], dep[N];
int dfn[N], rk[N];

int w[N], wt[N];

struct Graph {
    int v, nxt;
}e[M << 1];

int lk[N], ltp;

void ins(int u, int v) {
    e[++ltp] = (Graph) {v, lk[u]};
    lk[u] = ltp;
}

int top[N], cnt;
int mod;

void dfs1(int u) {
    son[u] = -1;
    siz[u] = 1;
    for(int i = lk[u]; i; i = e[i].nxt) {
        int v = e[i].v;
        if(!dep[v]) {
            dep[v] = dep[u] + 1;
            fa[v] = u;
            dfs1(v);
            siz[u] += siz[v];
            if(son[u] == -1 || siz[v] > siz[son[u]])
                son[u] = v;
        }
    }
}

void dfs2(int u, int t) {
    top[u] = t;
    ++cnt;
    dfn[u] = cnt;
    rk[cnt] = u;
    wt[cnt] = w[u];
    if(son[u] == -1) return ;
    dfs2(son[u], t);
    for(int i = lk[u]; i; i = e[i].nxt) {
        int v = e[i].v;
        if(v != son[u] && v != fa[u])
            dfs2(v, v);
    }
}

int lca(int u, int v) {
    while(top[u] != top[v]) {
        if(dep[top[u]] > dep[top[v]]) u = fa[top[u]];
        else v = fa[top[v]];
    }

    return dep[u] > dep[v] ? v : u;
}

struct Tree {
    int l, r;
    int dat, tag;

    #define l(x) t[x].l
    #define r(x) t[x].r
    #define dat(x) t[x].dat
    #define tag(x) t[x].tag

}t[N << 2];

void build(int p, int l, int r) {
    l(p) = l, r(p) = r;
    if(l == r) {
        dat(p) = wt[l];
        return ;
    }

    int mid = (r - l) / 2 + l;

    build(p << 1, l, mid);
    build(p << 1 | 1, mid + 1, r);

    dat(p) = (dat(p << 1) + dat(p << 1 | 1)) % mod;
}

void spr(int p) {
    if(tag(p)) {
        tag(p << 1) += tag(p);
        tag(p << 1 | 1) += tag(p);
        dat(p << 1) += tag(p) * (r(p << 1) - l(p << 1) + 1);
        dat(p << 1 | 1) += tag(p) * (r(p << 1 | 1) - l(p << 1 | 1) + 1);
        dat(p << 1) %= mod;
        dat(p << 1 | 1) %= mod;
        tag(p) = 0;
    }
}

void change(int p, int l, int r, int x) {
    if(l <= l(p) && r(p) <= r) {
        tag(p) += x;
        dat(p) += (r - l + 1) * x;
        dat(p) %= mod;
        return ;
    }

    spr(p);
    int mid = (r(p) - l(p)) / 2 + l(p);
    if(l <= mid) change(p << 1, l, r, x);
    if(r > mid) change(p << 1 | 1, l, r, x);
    dat(p) = (dat(p << 1) + dat(p << 1 | 1)) % mod;
}

int ask(int p, int l, int r) {
    int res = 0;
    if(l <= l(p) && r(p) <= r) return dat(p);

    spr(p);
    int mid = (r(p) - l(p)) / 2 + l(p);
    if(l <= mid) res += ask(p << 1, l, r);
    if(r > mid) res += ask(p << 1 | 1, l, r);

    return res;
}

int main() {
    n = rd(), m = rd(), q = rd(), mod = rd();
    for(int i = 1; i <= n; ++i)
        w[i] = rd();

    for(int i = 1; i < n; ++i) {
        int u = rd(), v = rd();
        ins(u, v);
        ins(v, u);
    }

    dep[q] = 1;
    dfs1(q);
    dfs2(q, q);

    build(1, 1, n);
    while(m--) {
        int opt = rd();
        if(opt == 1) {
            int u = rd(), v = rd(), w = rd();
            w %= mod;
            while(top[u] != top[v]) {
                if(dep[top[u]] < dep[top[v]]) swap(u, v);
                change(1, dfn[top[u]], dfn[u], w);
                u = fa[top[u]];
            }
            if(dep[u] > dep[v]) swap(u, v);
            change(1, dfn[u], dfn[v], w);
        } else if(opt == 2) {
            int u = rd(), v = rd();
            int ans = 0;
            while(top[u] != top[v]) {
                if(dep[top[u]] < dep[top[v]]) swap(u, v);
                ans += ask(1, dfn[top[u]], dfn[u]);
                ans %= mod;
                u = fa[top[u]];
            }

            if(dep[u] > dep[v]) swap(u, v);
            ans += ask(1, dfn[u], dfn[v]);
            printf("%d\n", ans % mod);
        } else if(opt == 3) {
            int u = rd(), w = rd();
            change(1, dfn[u], dfn[u] + siz[u] - 1, w);
        } else {
            int u = rd();
            printf("%d\n", ask(1, dfn[u], dfn[u] + siz[u] - 1));
        }
    }
    return 0;
}
2022/8/20 21:10
加载中...