Codeforces 383C Propagating tree(树状数组)

来源:互联网 发布:隐藏电脑录像软件 编辑:程序博客网 时间:2024/05/16 12:28

题目大意:

有一棵树,对这个树有两种操作:1:表示为(1 x val),在编号为x的节点上加上val,然后给x节点的每个儿子加上- val,再给每个儿子的儿子加上-(- val),一直加到没有儿子为止。2:表示为(2 x)查询x节点上的值。


思路:

首先通过dfs将树抽象成树状数组,然后以和根节点的层数关系作为d,开两个树状数组分别计算添加值和减少值。


#include<bits/stdc++.h>using namespace std;#define N 200005int bit[2][N], cnt, n;struct Node{    int l, r, val, d;}node[N];vector<int> g[N];void dfs(int u, int fa, int d){    node[u].l=++cnt;node[u].d=d;    for(int i=0; i<g[u].size(); i++)    {        int v=g[u][i];        if(v==fa) continue;        dfs(v, u, 1-d);    }    node[u].r=cnt;}void modify(int x, int val, int *sum){    while(x<=n)    {        sum[x]+=val;        x+=(x&(-x));    }}int getsum(int x, int *sum){    int ret=0;    while(x>0)    {        ret+=sum[x];        x-=(x&(-x));    }    return ret;}int main(){    int m, u, v, op;    while(scanf("%d%d", &n, &m)!=EOF)    {        cnt=0;        memset(bit, 0, sizeof(bit));        for(int i=1; i<=n; i++)        {            scanf("%d", &node[i].val);            g[i].clear();        }        for(int i=1; i<n; i++)        {            scanf("%d%d", &u, &v);            g[u].push_back(v);            g[v].push_back(u);        }        dfs(1, -1, 0);        for(int i=1; i<=m; i++)        {            scanf("%d", &op);            if(op==1)            {                scanf("%d%d", &u, &v);                modify(node[u].l, v, bit[node[u].d]);                modify(node[u].r+1, -v, bit[node[u].d]);                modify(node[u].l, -v, bit[1-node[u].d]);                modify(node[u].r+1, v, bit[1-node[u].d]);            }            else            {                scanf("%d", &u);                printf("%d\n", node[u].val+getsum(node[u].l, bit[node[u].d]));            }        }    }    return 0;}


阅读全文
0 0
原创粉丝点击