性感代码在线求调教

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

Slash_God @ 2024-07-12 18:38:10

厌氧


#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 10;
int n , m , r , mod , tp;
vector<int> q[N];
int fa[N] , dep[N] , sz[N] , son[N] , hd[N] , id[N] , a[N] , tree[N << 2] , tg[N << 2];
void dfs1(int x , int y){
    fa[x] = y;
    dep[x] = dep[y] + 1;
    sz[x] = 1;
    for(int i = 0; i < q[x].size(); i ++){
        int v = q[x][i];
        if(v == y) continue;
        dfs1(v , x);
        sz[x] += sz[v];
        if(sz[v] > sz[son[x]]) son[x] = v; 
    }
    return;
}
void dfs2(int x , int h){
    hd[x] = h;
    id[x] = ++ tp;
    if(son[x] != 0) dfs2(son[x] , h);
    for(int i = 0; i < q[x].size(); i ++){
        int v = q[x][i];
        if(v == son[x] || v == fa[x]) continue;
        dfs2(v , v);
    }
    return;
}
void down(int p , int l , int r){
    if (tg[p]) {
        int mid = l + r >> 1;
        tree[p << 1] = (tree[p << 1] + tg[p] * (mid - l + 1) % mod) % mod;
        tree[p << 1 | 1] = (tree[p << 1 | 1] + tg[p] * (r - mid) % mod) % mod;
        tg[p << 1] = (tg[p << 1] + tg[p]) % mod;
        tg[p << 1 | 1] = (tg[p << 1 | 1] + tg[p]) % mod;
        tg[p] = 0;
    }
}
void update(int p , int l , int r , int x , int y , int z){
    if (x > y) return;
    if(x <= l && r <= y){
        tg[p] += z;
        tree[p] += z * (r - l + 1);
        tree[p] %= mod;
        return ;
    }
    int mid = l + r >> 1;
    down(p, l, r);
    if (mid >= x) update(p << 1 , l , mid , x , y , z);
    if (mid < y) update(p << 1 | 1 , mid + 1 , r , x , y , z);
    tree[p] = (tree[p << 1] + tree[p << 1 | 1]) % mod;
}
int query(int p , int l , int r , int x , int y){
//  if(l > y || r < x) return 0;
    if (x > y) return 0; 
    if(x <= l && r <= y) return tree[p];
    int mid = l + r >> 1;
    int res = 0;
    down(p, l, r);
    if (mid >= x) res = (res + query(p << 1, l, mid, x, y)) % mod;
    if (mid < y) res = (res + query(p << 1 | 1, mid + 1, r, x, y)) % mod; 
    tree[p] = (tree[p << 1] + tree[p << 1 | 1]) % mod;
    return res;
}
int d1(int x , int y){
    int ans = 0;
    while(hd[x] != hd[y]){
        if(dep[hd[x]] < dep[hd[y]]) swap(x , y);
        ans = (ans + query(1 , 1 , n , id[hd[x]], id[x])) % mod;
        x = fa[hd[x]];
    }
    if(dep[x] < dep[y]) swap(x , y);
    ans = (ans + query(1 , 1 , n , id[y] , id[x])) % mod;
    return ans;
}
int d2(int x , int y , int z){
    while(hd[x] != hd[y]){
        if(dep[hd[x]] < dep[hd[y]]) swap(x , y);
        update(1 , 1 , n , id[hd[x]], id[x] , z);
        x = fa[hd[x]];
    }
    if(dep[x] < dep[y]) swap(x , y);
    update(1 , 1 , n , id[y] , id[x] , z);
}
signed main(){
    cin >> n >> m >> r >> mod;
    for(int i = 1; i <= n; i ++)
        cin >> a[i];
    for(int i = 1; i < n; i ++){
        int x , y;
        cin >> x >> y;
        q[x].push_back(y);
        q[y].push_back(x); 
    }
    dfs1(r , 0);
    dfs2(r , r);
    for(int i = 1; i <= n; i ++)
        update(1 , 1 , n , id[i] , id[i] , a[i]);
    while(m --){
        int op , x , y , z;
        cin >> op >> x;
        if(op == 1) cin >> y >> z , d2(x , y , z);
        if(op == 2) cin >> y , cout << d1(x , y) % mod << '\n';
        if(op == 3) cin >> z , update(1 , 1 , n , id[x] , id[x] + sz[x] - 1 , z); 
        if(op == 4) cout << query(1 , 1 , n , id[x] , id[x] + sz[x] - 1) % mod << '\n';
    }
    return 0;
}

by wuzijie @ 2024-07-12 18:42:17

%%%


by gavinliu266 @ 2024-07-12 18:43:04

d2 没有返回值


by Ace_FutureDream @ 2024-07-12 18:47:32

%%% @wuzijie


by Slash_God @ 2024-07-12 18:54:02

谢谢


|