样例没过,求调错

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

LiuTianyou @ 2023-01-31 19:24:53

#include <bits/stdc++.h>
#define int long long
using namespace std;
vector<list<int> > tree;
int n, m, r, p;
int val[100005], depth[100005], father[100005], siz[100005], son[100005];
int dfn[100005], top[100005], nval[100005], cnt = 0;
struct SegmentTree{
    struct node{
        int left, right;
        int sum, lazytag;
    }tree[100005];
    void pushdown(int p){
        if(tree[p].lazytag){
            tree[p * 2].sum += tree[p].lazytag * (tree[p * 2].right - tree[p * 2].left + 1) % p;
            tree[p * 2 + 1].sum += tree[p].lazytag * (tree[p * 2 + 1].right - tree[p * 2 + 1].left + 1) % p;
            tree[p * 2].lazytag += tree[p].lazytag;
            tree[p * 2 + 1].lazytag += tree[p].lazytag;
            tree[p].lazytag = 0;
        }
    }
    void build(int p, int l, int r){
        tree[p].left = l, tree[p].right = r;
        if(l == r){
            tree[p].sum = nval[l] % p;
            return;
        }
        int mid = (l + r) / 2;
        build(p * 2, l, mid);
        build(p * 2 + 1, mid + 1, r);
        tree[p].sum = (tree[p * 2].sum + tree[p * 2 + 1].sum) % p;
        return;
    }
    void add(int p, int l, int r, int v){
        if(l <= tree[p].left && tree[p].right <= r){
            tree[p].lazytag = (tree[p].lazytag + v) % p;
            tree[p].sum = (tree[p].sum + v * (tree[p].right - tree[p].left + 1)) % p;
            return;
        }
        pushdown(p);
        int mid = (tree[p].left + tree[p].right) / 2;
        if(l <= mid) add(p * 2, l, r, v);
        if(r > mid) add(p * 2 + 1, l, r, v);
        tree[p].sum = (tree[p * 2].sum + tree[p * 2 + 1].sum) % p;
        return;
    }
    int query(int p, int l, int r){
        if(l <= tree[p].left && tree[p].right <= r){
            return tree[p].sum;
        }
        pushdown(p);
        int mid = (tree[p].left + tree[p].right) / 2, ret = 0;
        if(l <= mid) ret += query(p * 2, l, r);
        if(r > mid) ret += query(p * 2 + 1, l, r);
        return ret % p;
    }
}STree;
void dfs1(int x, int fa){
    int maxson = -1;
    depth[x] = depth[fa] + 1, father[x] = fa, siz[x] = 1;
    for(auto it = tree[x].begin(); it != tree[x].end(); it++){
        if(*it != fa){
            dfs1(*it, x);
            siz[x] += siz[*it];
            if(siz[*it] > maxson) son[x] = *it, maxson = siz[*it];
        }
    }
}
void dfs2(int x, int topf){
    dfn[x] = ++cnt, nval[cnt] = val[x], top[x] = topf;
    if(son[x] == 0) return;
    dfs2(son[x], topf);
    for(auto it = tree[x].begin(); it != tree[x].end(); it++){
        if(*it == father[x] || *it == son[x]) continue;
        dfs2(*it, *it);
    }
}
signed main(){
    scanf("%lld %lld %lld %lld", &n, &m, &r, &p);
    tree.resize(n + 1);
    for(int i = 1; i <= n; i++) scanf("%lld", &val[i]);
    for(int i = 1, x, y; i <= n - 1; i++){
        scanf("%lld %lld", &x, &y);
        tree[x].push_back(y);
        tree[y].push_back(x);
    }
    dfs1(r, 0);
    dfs2(r, r);
    STree.build(1, 1, n);
    while(m--){
        int op, x, y, z;
        scanf("%lld", &op);
        if(op == 1){
            scanf("%lld %lld %lld", &x, &y, &z);
            z %= p;
            while(top[x] != top[y]){
                if(depth[top[x]] < depth[top[y]]) swap(x, y);
                STree.add(1, dfn[top[x]], dfn[x], z);
                x = father[top[x]];
            }
            if(depth[x] < depth[y]) swap(x, y);
            STree.add(1, dfn[x], dfn[y], z);
        }else if(op == 2){
            int ans = 0;
            scanf("%lld %lld", &x, &y);
            while(top[x] != top[y]){
                if(depth[top[x]] < depth[top[y]]) swap(x, y);
                ans = (ans + STree.query(1, dfn[top[x]], dfn[x])) % p;
                x = father[top[x]];
            }
            if(depth[x] < depth[y]) swap(x, y);
            ans = (ans + STree.query(1, dfn[x], dfn[y])) % p;
            printf("%lld\n", ans);
        }else if(op == 3){
            scanf("%lld %lld", &x, &z);
            STree.add(1, dfn[x], dfn[x] + siz[x] - 1, z);
        }else{
            scanf("%lld", &x);
            printf("%lld\n", STree.query(1, dfn[x], dfn[x] + siz[x] - 1));
        }
    }
    return 0;
}

会有人搭理我嘛


by LiuTianyou @ 2023-01-31 20:01:23

@MSqwq 对不起……我错了


by LiuTianyou @ 2023-01-31 20:03:00

@MSqwq 谢谢你了


by MSqwq @ 2023-01-31 20:04:03

@LiuTianyou 没事没事,以后注意一下就好啦


by LiuTianyou @ 2023-01-31 20:04:46

@MSqwq 对不起,今天脑子真的非常非常乱,给你添麻烦了。。。


上一页 |