DFS序

DFS序


题目链接:DFS序2


DFS序

其实是利用时间戳按照DFS访问顺序对每个节点标号

in[p] : 以p(节点编号)为根节点的子树的开头

out[p] : 以p(节点编号)为根节点的子树的结尾

​ 例 : in[1] = 4, out[1] = 8, 代表以节点编号1为根节点的子树, DFS序对应时间戳为[4,8]

dfs_order[] : 存储节点编号, 索引为时间戳

​ 例 : dfs_order[1] = 4, 代表DFS序为1的点,对应的节点编号为4


AC代码

#include <iostream>
#include <vector>
#define ll long long
#define ls u << 1
#define rs u << 1 | 1
using namespace std;

const int N = 1e6 + 10;
int n, m, r, idx;
int a[N], in[N], out[N], dfs_order[N];
bool vis[N];
vector<int> G[N];

struct node{
    int l, r;
    ll sum, lazy;
}tr[N << 2];

void pushup(int u){
    tr[u].sum = tr[ls].sum + tr[rs].sum;
}

void pushdown(int u){
    if(tr[u].lazy){
        tr[ls].sum += (tr[ls].r - tr[ls].l + 1) * tr[u].lazy, tr[rs].sum += (tr[rs].r - tr[rs].l + 1) * tr[u].lazy;
        tr[ls].lazy += tr[u].lazy, tr[rs].lazy += tr[u].lazy;
        tr[u].lazy = 0;
    }
}

void build(int l, int r, int u){
    tr[u].l = l, tr[u].r = r, tr[u].lazy = 0;
    if(l == r){
        tr[u].sum = a[dfs_order[l]];
        return;
    }
    int mid = (l + r) >> 1;
    build(l, mid, ls), build(mid+1, r, rs);
    pushup(u);
}

void add(int l, int r, int u, ll v){
    if(l <= tr[u].l && r >= tr[u].r){
        tr[u].sum += (tr[u].r - tr[u].l + 1) * v;
        tr[u].lazy += v;
        return;
    }
    pushdown(u);
    int mid = (tr[u].l + tr[u].r) >> 1;
    if(l <= mid) add(l, r, ls, v);
    if(r > mid) add(l, r, rs, v);
    pushup(u);
}


ll query(int l, int r, int u){
    if(l <= tr[u].l && r >= tr[u].r) return tr[u].sum;
    int mid = (tr[u].l + tr[u].r) >> 1;
    pushdown(u);
    ll ans = 0;
    if(l <= mid) ans += query(l, r, ls);
    if(r > mid) ans += query(l, r, rs);
    return ans;
}

void dfs(int p){
    in[p] = ++idx;
    dfs_order[idx] = p; // 记录某个时间访问到的节点编号
    vis[p] = true;
    for(int it : G[p])
        if(!vis[it]) dfs(it);
    out[p] = idx;
}


int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);

    cin >> n >> m >> r;
    for(int i = 1; i <= n; i++) cin >> a[i];
    for(int i = 1; i < n; i++){
        int a, b;
        cin >> a >> b;
        G[a].push_back(b);
        G[b].push_back(a);
    }
    dfs(r);
    build(1, n, 1);
    while(m--){
        int op, a, x;
        cin >> op >> a;
        if(op == 1){
            cin >> x;
            add(in[a], out[a], 1, x);
        }
        else{
            cout << query(in[a], out[a], 1) << "\n";
        }
    }
    return 0;
}
posted @ 2024-05-08 17:21  XiaoFeng0432  阅读(10)  评论(0)    收藏  举报