【DFS序+树状数组】#144. DFS 序 1

 

 

 

每个点记录一个进入的时间和出来的时间

这样就能保证每个子树内的点的顺序是连着的

然后就可以利用树状数组维护单点修改,区间查询了

 

 

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
int n,m,root,cnt,times;
int v[maxn],l[maxn],r[maxn],head[maxn];
long long c[maxn];
struct edge
{
    int to,nxt;
}e[maxn<<2];
void add(int x,int y)
{
    e[++cnt].to=y;
    e[cnt].nxt=head[x];
    head[x]=cnt;
}
int lowbit(int x)
{
    return x&(-x);
}
void modify(int x,int val)
{
    for(;x<=n;x+=lowbit(x))
        c[x]+=val;
}
void dfs(int u,int fa)
{
    l[u]=++times;
    modify(l[u],v[u]);
    for(int i=head[u];i;i=e[i].nxt)
    {
        int to=e[i].to;
        if(to==fa) continue;
        dfs(to,u);
    }
    r[u]=times;
}
long long query(int x)
{
    long long res=0;
    for(;x>=1;x-=lowbit(x))
        res+=c[x];
    return res;
}
int main()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    scanf("%d%d%d",&n,&m,&root);
    for(int i=1;i<=n;i++) scanf("%d",&v[i]);
    int x,y;
    for(int i=1;i<n;i++)
    {
        scanf("%d%d",&x,&y);
        add(x,y); add(y,x);
    }
    dfs(root,0);
    for(int i=1;i<=m;i++)
    {
        int op; scanf("%d",&op);
        if(op==1)
        {
            scanf("%d%d",&x,&y);
            modify(l[x],y);
        }
        else
        {
            scanf("%d",&x);
            printf("%lld\n",query(r[x])-query(l[x]-1));
        }
    }
    return 0;
}

 

posted @ 2020-11-27 18:10  andyc_03  阅读(144)  评论(0编辑  收藏  举报