DFS序维护树状数组

 

dfs序是指:每个节点在dfs深度优先遍历中的进出栈的时间序列。 

 

如图,当我们维护一个时间戳,即每个节点进栈与出栈的时间,便可以把树上问题转换为区间问题。

例题如下: 

 当我们需要对树上问题进行区间求和的时候,如果我们可以把树上问题转为区间问题,便可以很方便的利用数组数组以及线段树去维护序列,

#include<bits/stdc++.h>
#define int long long 
using namespace std;
const int N = 1e6 + 10;
const int M = N * 2;
int n,m,k;
int vv[N];
int h[N],e[M],ne[M],idx;
int c[N];
int l[N];
int r[N];
int ti;
int ask(int x)
{
    int ans = 0;
    for(; x ; x -= (x & - x)) ans += c[x];
    return ans ; 
} 

void ad(int x,int y)
{
    for(; x <= N; x+= x & - x) c[x] += y;
}
void add (int a,int b)
{
    e[idx]=b;
    ne[idx]=h[a];
    h[a]=idx++;
}

void dfs(int u,int fa)
{
    l[u] = ++ti;
    for(int i = h[u];i != - 1 ; i = ne[i])
        if(e[i] != fa) dfs(e[i],u);
    r[u] = ti;
}
signed main()
{
    memset(h,-1,sizeof h);
    cin >> n >> m >> k;
    for(int i = 1 ; i <= n ; i++) cin >> vv[i];
    int x,y;
    for(int i = 1; i < n ; i++)
    {
        cin >> x >> y;
        add(x,y);
        add(y,x);
    }
    dfs(k,0);
    int op,u,v;
    for(int i = 1 ; i <= n ; i++)
    {
        ad(l[i],vv[i]);
    }
    for(int i = 1 ; i <= m ; i++)
    {
        cin >> op;
        if(op == 1)
        {
            cin >> u >> v;
            ad(l[u],v);
        }
        else if(op == 2)
        {
            cin >> u;
            cout << ask(r[u]) - ask(l[u] - 1) << endl;
        }
    }

}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值