CodeForces 384E Propagating tree (dfs序)

来源:互联网 发布:贪吃蛇java课程设计 编辑:程序博客网 时间:2024/06/07 09:58

题目传送门:http://codeforces.com/problemset/problem/384/E
题意:给你一棵树,根节点1,每个节点有权值,然后你可以对一个节点进行操作,在它的权值上加上val,但是它的子节点需要加上val,它的子节点的子节点就要加上(val),就是子节点加得的值和父节点相反,询问你某个节点当前的权值。
题解:修改一个节点,子树上的其他节点都被修改,很像dfs序诶,实际上确实就是,但是这个不像前面一样一个区间里面一样的操作,它在区间里的操作有的是加val,有的是减val,这该如何是好呢。其实考虑到对于一个子树,一层是加,一层是减,一层加,一层减,这样的,所以可以对每一层的节点,设置一个col值,对于整棵树,偶数层的节点col=1,奇数层的节点col=0,然后更新的时候,如果是对奇数层的节点更新,那么把val=val,因为奇数层是需要+val,但是由于奇数层节点的col=1,所以需要把val变为负的,再相乘,col等于一个符号的作用吧,偶数层不变,然后最后查询时候返回的值为sum[rt]+add[rt]col[rt],其中sum为原来这个节点的值,add为后来加上去的值,col为这个节点的符号。

代码:

#include <map>#include <set>#include <stack>#include <queue>#include <cmath>#include <string>#include <vector>#include <cstdio>#include <cctype>#include <cstring>#include <sstream>#include <cstdlib>#include <iostream>#include <algorithm>#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;#define   MAX           200005#define   MAXN          6005#define   maxnode       15#define   sigma_size    30#define   lson          l,m,rt<<1#define   rson          m+1,r,rt<<1|1#define   lrt           rt<<1#define   rrt           rt<<1|1#define   middle        int m=(r+l)>>1#define   LL            long long#define   ull           unsigned long long#define   mem(x,v)      memset(x,v,sizeof(x))#define   lowbit(x)     (x&-x)#define   pii           pair<int,int>#define   bits(a)       __builtin_popcount(a)#define   mk            make_pair#define   limit         10000//const int    prime = 999983;const int    INF   = 0x3f3f3f3f;const LL     INFF  = 0x3f3f;const double pi    = acos(-1.0);//const double inf   = 1e18;const double eps   = 1e-8;const LL    mod    = 1e9+7;const ull    mx    = 133333331;/*****************************************************/inline void RI(int &x) {      char c;      while((c=getchar())<'0' || c>'9');      x=c-'0';      while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0'; }/*****************************************************/struct Edge{    int v,next;}edge[MAX*2];int head[MAX];int tot;int c[MAX];int p1[MAX];int p2[MAX];int dep[MAX];int ti;int dfsnum[MAX];LL sum[MAX<<2];int col[MAX<<2];int add[MAX<<2];void init(){    mem(head,-1);    tot=0;ti=0;}void add_edge(int a,int b){    edge[tot]=(Edge){b,head[a]};    head[a]=tot++;}void dfs(int u,int fa,int d){    p1[u]=++ti;    dep[u]=d;    dfsnum[ti]=u;    for(int i=head[u];i!=-1;i=edge[i].next){        int v=edge[i].v;        if(v==fa) continue;        dfs(v,u,d+1);    }    p2[u]=ti;}void pushdown(int rt){    if(add[rt]){        add[lrt]+=add[rt];        add[rrt]+=add[rt];        add[rt]=0;    }}void build(int l,int r,int rt){    add[rt]=0;    if(l==r){        sum[rt]=c[dfsnum[l]];        if(dep[dfsnum[l]]&1) col[rt]=-1;        else col[rt]=1;        return;    }    middle;    build(lson);    build(rson);}void update(int l,int r,int rt,int L,int R,int d){    if(L<=l&&r<=R){        add[rt]+=d;        return;    }    middle;    pushdown(rt);    if(L<=m) update(lson,L,R,d);    if(R>m) update(rson,L,R,d);}int query(int l,int r,int rt,int pos){    if(l==r){        return sum[rt]+add[rt]*col[rt];    }    middle;    pushdown(rt);    if(pos<=m) return query(lson,pos);    else return query(rson,pos);}int main(){    //freopen("in.txt","r",stdin);    int n,m;    while(cin>>n>>m){        init();        for(int i=1;i<=n;i++) scanf("%d",&c[i]);        for(int i=1;i<n;i++){            int a,b;            scanf("%d%d",&a,&b);            add_edge(a,b);            add_edge(b,a);        }        dfs(1,-1,0);        build(1,n,1);        //for(int i=1;i<=n;i++) cout<<p1[i]<<endl;        while(m--){            int op,a;            scanf("%d%d",&op,&a);            if(op==1){                int val;                scanf("%d",&val);                if(dep[a]&1) val=-val;                update(1,n,1,p1[a],p2[a],val);                //for(int i=1;i<=n;i++){ cout<<query(1,n,1,p1[i])<<" ";}                //cout<<endl;            }            else printf("%d\n",query(1,n,1,p1[a]));        }    }    return 0;}
0 0