蒟蒻10pts代码求调(献上膝盖)

P3384 【模板】重链剖分/树链剖分

wanghaolin44243787 @ 2024-08-07 20:51:39

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define MAXN 100005
ll n, m, r, mod, a[MAXN], ans[MAXN << 2], tag[MAXN << 2], id[MAXN], x, y, z, w, tot[MAXN], fa[MAXN], top[MAXN], dep[MAXN], son[MAXN], cnt, v[MAXN], t;
vector<ll>edge[MAXN];
inline void dfs1(ll now, ll f, ll dp) {
    fa[now] = f;
    dep[now] = dp;
    tot[now] = 1;
    ll maxson = -1;
    for (int i = 0; i < edge[now].size(); i++) {
        if (edge[now][i] == f) {
            continue;
        }
        dfs1(edge[now][i], now, dp + 1);
        tot[now] += tot[edge[now][i]];
        if (maxson < max(tot[edge[now][i]], maxson)) {
            maxson = max(tot[edge[now][i]], maxson);
            son[now] = edge[now][i];
        }
    }
    return;
}
inline void dfs2(ll now, ll topof) {
    id[now] = ++cnt;
    v[cnt] = a[now];
    top[now] = topof;
    if (son[now] == 0)return;
    dfs2(son[now], topof);
    for (int i = 0; i < edge[now].size(); i++) {
        if (id[edge[now][i]] == 0) {
            dfs2(edge[now][i], edge[now][i]);
        }
    }
    return;
}
inline void push_back(ll p, ll l, ll r) {
    ll mid = l / 2.0 + r / 2.0;
    ans[p * 2] += tag[p] * (l - mid + 1);
    ans[p * 2] %= mod;
    tag[p * 2] += tag[p];
    tag[p * 2] %= mod;
    ans[p * 2 + 1] += tag[p] * (r - mid);
    ans[p * 2 + 1] %= mod;
    tag[p * 2 + 1] += tag[p];
    tag[p * 2 + 1] %= mod;
    tag[p] = 0;
}
inline void build(ll p, ll l, ll r) {
    if (l == r) {
        ans[p] = v[l];
        return;
    }
    ll mid = l / 2.0 + r / 2.0;
    build(p * 2, l, mid);
    build(p * 2 + 1, mid + 1, r);
    ans[p] = ans[p * 2] + ans[p * 2 + 1];
    ans[p] %= mod;
    return;
}
inline void update(ll dl, ll dr, ll l, ll r, ll p, ll k) {
    k %= mod;
    if (dl <= l && dr >= r) {
        ans[p] += k * (r - l + 1);
        ans[p] %= mod;
        tag[p] += k;
        tag[p] %= mod;
        return ;
    }
    ll mid = l / 2.0 + r / 2.0;
    push_back(p, l, r);
    if (dl <= mid)update(dl, dr, l, mid, p * 2, k);
    if (dr > mid)update(dl, dr, mid + 1, r, p * 2 + 1, k);
    ans[p] = ans[p * 2] + ans[p * 2 + 1];
    ans[p] %= mod;
    return;
}
ll query(ll dl, ll dr, ll l, ll r, ll p) {
    if (dl <= l && dr >= r)return ans[p];
    ll sum = 0;
    ll mid = l / 2.0 + r / 2.0;
    push_back(p, l, r);
    if (dl <= mid) {
        sum += query(dl, dr, l, mid, p * 2);
        sum %= mod;
    }
    if (dr > mid) {
        sum += query(dl, dr, mid + 1, r, p * 2 + 1);
        sum %= mod;
    }
    return sum % mod;
}
inline void tree_update(ll a, ll b, ll c) {
    while (top[a] != top[b]) {
        if (dep[top[a]] < dep[top[b]])swap(a, b);
        update(id[top[a]], id[a], 1, n, 1, c);
        a = fa[top[a]];
    }
    if (dep[a] > dep[b])swap(a, b);
    update(id[x], id[y], 1, n, 1, c);
    return;
}
ll tree_query(ll a, ll b) {
    ll qq = 0;
    while (top[a] != top[b]) {
        if (dep[top[a]] < dep[top[b]])swap(a, b);
        qq += query(id[top[a]], id[a], 1, n, 1);
        qq %= mod;
        a = fa[top[a]];
    }
    if (dep[a] > dep[b])swap(a, b);
    qq += query(id[x], id[y], 1, n, 1);
    qq %= mod;
    return qq % mod;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> m >> r >> mod;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    for (int i = 1; i < n; i++) {
        cin >> x >> y;
        edge[x].push_back(y);
        edge[y].push_back(x);
    }
    dfs1(r, 0, 1);
    dfs2(r, r);
    build(1, 1, n);
    for (int i = 1; i <= m; i++) {
        cin >> x;
        if (x == 1) {
            cin >> y >> z >> w;
            tree_update(y, z, w);
        } else if (x == 2) {
            cin >> y >> z;
            cout << tree_query(y, z) << "\n";
        } else if (x == 3) {
            cin >> y >> z;
            update(id[y], id[y] + tot[y] - 1, 1, n, 1, z);
        } else if (x == 4) {
            cin >> y;
            cout << query(id[y], id[y] + tot[y] - 1, 1, n, 1) % mod << "\n";
        }
    }
    return 0;
}

by wanghaolin44243787 @ 2024-08-08 09:44:38

inline void tree_update(ll a, ll b, ll c) {
    while (top[a] != top[b]) {
        if (dep[top[a]] < dep[top[b]])swap(a, b);
        update(id[top[a]], id[a], 1, n, 1, c);
        a = fa[top[a]];
    }
    if (dep[a] > dep[b])swap(a, b);
    update(id[x], id[y], 1, n, 1, c);
    return;
}
ll tree_query(ll a, ll b) {
    ll qq = 0;
    while (top[a] != top[b]) {
        if (dep[top[a]] < dep[top[b]])swap(a, b);
        qq += query(id[top[a]], id[a], 1, n, 1);
        qq %= mod;
        a = fa[top[a]];
    }
    if (dep[a] > dep[b])swap(a, b);
    qq += query(id[x], id[y], 1, n, 1);
    qq %= mod;
    return qq % mod;
}

改为

inline void tree_update(ll a, ll b, ll c) {
    while (top[a] != top[b]) {
        if (dep[top[a]] < dep[top[b]])swap(a, b);
        update(id[top[a]], id[a], 1, n, 1, c);
        a = fa[top[a]];
    }
    if (dep[a] > dep[b])swap(a, b);
    update(id[a], id[b], 1, n, 1, c);
    return;
}
ll tree_query(ll a, ll b) {
    ll qq = 0;
    while (top[a] != top[b]) {
        if (dep[top[a]] < dep[top[b]])swap(a, b);
        qq += query(id[top[a]], id[a], 1, n, 1);
        qq %= mod;
        a = fa[top[a]];
    }
    if (dep[a] > dep[b])swap(a, b);
    qq += query(id[a], id[b], 1, n, 1);
    qq %= mod;
    return qq % mod;
}

by wanghaolin44243787 @ 2024-08-08 09:45:46

此贴结


by Eastern_Leaf @ 2024-08-08 11:49:02

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


by ChangeYuAN @ 2024-08-08 17:41:56

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


|