树剖+线段树 求调玄关
查看原帖
树剖+线段树 求调玄关
965366
zcrswe楼主2025/6/25 20:00
#include<bits/stdc++.h>
#define int long long 
#define mid (pl + pr >> 1)
#define ls (p << 1)
#define rs (p << 1 | 1)
using namespace std;
const int N = 1e5 + 5;
int w[N], dep[N], fa[N], son[N], siz[N], top[N], id[N];
int cnt, n, m;
vector<int> E[N];
void dfs1(int u, int f){
    fa[u] = f;
    dep[u] = dep[f] + 1;
    for(auto k : E[u])
        if(k != f)dfs1(k, u);
    siz[u] = 1;
    for(auto k : E[u]){
        if(k == f)continue;
        siz[u] += siz[k];
        if(siz[k] > siz[son[u]])son[u] = k;
    }
    return;
}
void dfs2(int u, int f){
    top[u] = f;
    id[u] = ++ cnt;
    if(son[u])dfs2(son[u], f);
    for(auto k : E[u]){
        if(k == fa[u] || k == son[u])continue;
        dfs2(k, k);
    }
}
int tree[N << 2], lzy[N << 2];
void build(int p, int pl, int pr){
    if(pl == pr){
        tree[p] = w[id[pl]];
        return;
    }
    build(ls, pl, mid);
    build(rs, mid + 1, pr);
    tree[p] = tree[ls] + tree[rs];
    return;
}
inline void push_down(int p, int pl, int pr){
    if(lzy[p]){
        tree[ls] += lzy[p] * (mid - pl + 1);
        tree[rs] += lzy[p] * (pr - mid);
        lzy[ls] += lzy[p];
        lzy[rs] += lzy[p];
        lzy[p] = 0;
    }
    return;
}
void add(int p, int pl, int pr, int l, int r, int k){
    if(l > r) swap(l, r);
    if(l <= pl && pr <= r){
        tree[p] += k * (pr - pl + 1);
        lzy[p] += k;
        return;
    }
    push_down(p, pl, pr);
    if(mid >= l)add(ls, pl, mid, l, r, k);
    if(mid < r)add(rs, mid + 1, pr, l, r, k);
    tree[p] = tree[ls] + tree[rs];
    return;
}
int que(int p, int pl, int pr, int l, int r){
    if (l > r) swap(l, r);
    if(l <= pl && pr <= r)return tree[p];
    push_down(p, pl, pr);
    int res = 0;
    if(mid >= l)res += que(ls, pl, mid, l, r);
    if(mid < r)res += que(rs, mid + 1, pr, l, r);
    tree[p] = tree[ls] + tree[rs];
    return res;
}
inline void add_point(int p, int k){
    add(1, 1, n, id[p], id[p], k);
    return;
}
inline void add_tree(int p, int k){
    add(1, 1, n, id[p], id[p] + siz[p] - 1, k);
    return;
}
inline int que_road(int p){
    int res = 0;
    while(p){
        res += que(1, 1, n, id[top[p]], id[p]);
        p = fa[top[p]];
    }
    return res;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin >> n >> m;
    for(int i = 1;i <= n;i ++)
        cin >> w[i];
    for(int i = 1;i <= n - 1;i ++){
        int u, v;cin >> u >> v;
        E[u].push_back(v);
        E[v].push_back(u);
    }
    dfs1(1, 0);
    dfs2(1, 1);
    build(1, 1, n);
    // for(int i = 1;i <= n;i ++)
    //     cout << id[i] << '\n';
    for(int i = 1;i <= m;i ++){
        int op; cin >> op;
        if(op == 1){
            int p, k;cin >> p >> k;
            add_point(p, k);
        }
        if(op == 2){
            int p, k;cin >> p >> k;
            add_tree(p, k);
        }
        if(op == 3){
            int p;cin >> p;
            cout << que_road(p) << '\n';
        }
    }
    for(int i = 1;i <= n;i ++){
        cout << siz[i] << ' ';
    }
    return 0;
}
2025/6/25 20:00
加载中...