【DFS序+线段树】#145. DFS 序 2

 

 

 

 

 

这道题目和DFS1基本一致,修改的为区间,所以使用线段树

 

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
int n,m,root,cnt,times;
int v[maxn],le[maxn],ri[maxn],num[maxn],head[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;
}
struct point
{
    int l,r;
    long long val,lz;
}tr[maxn<<2];
void dfs(int u,int fa)
{
    le[u]=++times; num[times]=u;
    for(int i=head[u];i;i=e[i].nxt)
    {
        int to=e[i].to;
        if(to==fa) continue;
        dfs(to,u);
    }
    ri[u]=times;
}
void pushup(int now)
{
    tr[now].val=tr[now<<1].val+tr[now<<1|1].val;
}
void build(int now,int l,int r)
{
    tr[now].l=l; tr[now].r=r;
    if(l==r)
    {
        tr[now].val=v[num[l]];
        return;
    }
    int mid=(l+r)>>1;
    build(now<<1,l,mid);
    build(now<<1|1,mid+1,r);
    pushup(now);
}
void pushdown(int now)
{
    if(!tr[now].lz) return;
    tr[now<<1].lz+=tr[now].lz;
    tr[now<<1|1].lz+=tr[now].lz;
    tr[now<<1].val+=1LL*(tr[now<<1].r-tr[now<<1].l+1)*tr[now].lz;
    tr[now<<1|1].val+=1LL*(tr[now<<1|1].r-tr[now<<1|1].l+1)*tr[now].lz;
    tr[now].lz=0;
    return;
}
void update(int now,int l,int r,int val)
{
    if(tr[now].l>=l && tr[now].r<=r)
    {
        tr[now].val+=1LL*val*(tr[now].r-tr[now].l+1);
        tr[now].lz+=val;
        return;
    }
    pushdown(now);
    int mid=(tr[now].l+tr[now].r)>>1;
    if(l<=mid) update(now<<1,l,r,val);
    if(r>mid) update(now<<1|1,l,r,val);
    pushup(now);
}
long long query(int now,int l,int r)
{
    if(tr[now].l>=l && tr[now].r<=r)
        return tr[now].val;
    int mid=(tr[now].l+tr[now].r)>>1;
    pushdown(now);
    long long res=0;
    if(l<=mid) res+=query(now<<1,l,r);
    if(r>mid) res+=query(now<<1|1,l,r);
    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);
    build(1,1,n);
    for(int i=1;i<=m;i++)
    {
        int op; scanf("%d",&op);
        if(op==1)
        {
            scanf("%d%d",&x,&y);
            update(1,le[x],ri[x],y);
        }
        else
        {
            scanf("%d",&x);
            printf("%lld\n",query(1,le[x],ri[x]));
        }
    }
    return 0;
}

 

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