Propagating tree CodeForces - 384E

点击打开链接

思维水题 每个区间维护两个值 一个是来自偶数层节点的累加值 另一个是来自奇数层节点的累加值

因为是单点查询 pushup和pushdown都扔掉就 一路加到底即可

#include 
using namespace std;

struct node1
{
    int v;
    int next;
};

struct node2
{
    int l;
    int r;
    int val[2];
};

node1 edge[400010];
node2 tree[800010];
int pre[200010],first[200010],deep[200010],mp[200010],sum[200010];
int n,q,num,ans;

void addedge(int u,int v)
{
    edge[num].v=v;
    edge[num].next=first[u];
    first[u]=num++;
    return;
}

void build(int l,int r,int cur)
{
    int m;
    tree[cur].l=l;
    tree[cur].r=r;
    tree[cur].val[0]=0;
    tree[cur].val[1]=0;
    if(l==r) return;
    m=(l+r)/2;
    build(l,m,2*cur);
    build(m+1,r,2*cur+1);
    return;
}

void dfs(int cur,int fa)
{
    int i,v;
    mp[cur]=++num,sum[cur]=1;
    for(i=first[cur];i!=-1;i=edge[i].next)
    {
        v=edge[i].v;
        if(v!=fa)
        {
            deep[v]=deep[cur]+1;
            dfs(v,cur);
            sum[cur]+=sum[v];
        }
    }
    return;
}

void update(int pl,int pr,int dep,int val,int cur)
{
    if(pl<=tree[cur].l&&tree[cur].r<=pr)
    {
        tree[cur].val[dep]+=val;
        return;
    }
    if(pl<=tree[2*cur].r) update(pl,pr,dep,val,2*cur);
    if(pr>=tree[2*cur+1].l) update(pl,pr,dep,val,2*cur+1);
    return;
}

void query(int tar,int dep,int cur)
{
    if(dep) ans+=(tree[cur].val[1]-tree[cur].val[0]);
    else ans+=(tree[cur].val[0]-tree[cur].val[1]);
    if(tree[cur].l==tree[cur].r) return;
    if(tar<=tree[2*cur].r) query(tar,dep,2*cur);
    else query(tar,dep,2*cur+1);
    return;
}

int main()
{
    int i,u,v,op,val;
    scanf("%d%d",&n,&q);
    for(i=1;i<=n;i++)
    {
        scanf("%d",&pre[i]);
    }
    build(1,n,1);
    memset(first,-1,sizeof(first));
    num=0;
    for(i=1;i<=n-1;i++)
    {
        scanf("%d%d",&u,&v);
        addedge(u,v);
        addedge(v,u);
    }
    deep[1]=1;
    num=0;
    dfs(1,-1);
    while(q--)
    {
        scanf("%d",&op);
        if(op==1)
        {
            scanf("%d%d",&u,&val);
            update(mp[u],mp[u]+sum[u]-1,deep[u]%2,val,1);
        }
        else
        {
            scanf("%d",&u);
            ans=pre[u];
            query(mp[u],deep[u]%2,1);
            printf("%d\n",ans);
        }
    }
    return 0;
}

 

你可能感兴趣的:(线段树/树状数组/RMQ)