栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

DFS序维护树状数组

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

DFS序维护树状数组

 

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

 

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

例题如下: 

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

#include
#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;
        }
    }

}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/783804.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号