Codeforces Round #225 (Div. 1) C-Propagating tree (DFS序+线段树/树状数组)

题目链接:http://codeforces.com/contest/383/problem/C



Description

Iahub likes trees very much. Recently he discovered an interesting tree named propagating tree. The tree consists of n nodes numbered from 1 to n, each node i having an initial value ai. The root of the tree is node 1.

This tree has a special property: when a value val is added to a value of node i, the value -val is added to values of all the children of node i. Note that when you add value -val to a child of node i, you also add -(-val) to all children of the child of node i and so on. Look an example explanation to understand better how it works.

This tree supports two types of queries:

    "1 x val" — val is added to the value of node x;
    "2 x" — print the current value of node x. 

In order to help Iahub understand the tree better, you must answer m queries of the preceding type.

Input

The first line contains two integers n and m (1 ≤ n, m ≤ 200000). The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 1000). Each of the next n–1 lines contains two integers vi and ui (1 ≤ vi, ui ≤ n), meaning that there is an edge between nodes vi and ui.

Each of the next m lines contains a query in the format described above. It is guaranteed that the following constraints hold for all queries: 1 ≤ x ≤ n, 1 ≤ val ≤ 1000.

Output

For each query of type two (print the value of node x) you must print the answer to the query on a separate line. The queries must be answered in the order given in the input.

Sample Input

5 5
1 2 1 1 2
1 2
1 3
2 4
2 5
1 2 3
1 1 2
2 1
2 2
2 4

Sample Output

3
3
0



题意给出一颗有n个节点,且1为根节点的树,每个节点有它的权值,现在进行m次操作,操作分为添加和查询,当一个节点的权值添加v,则它的孩子节点的权值要添加-v。

题解:DFS标号后,按照深度分出奇偶层,当奇数(偶数)层+v时,对应偶数(奇数)层-v,两个线段树跑一跑就好。

线段树:


//#include <bits/stdc++.h>
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define LL long long
#define bug cout<<"bug"<<endl
const int MAXN = 2e5+7;
int n,m,index;
int val[MAXN],lazy[2][MAXN<<2];
vector<int> node[MAXN];
int deep,L[MAXN],R[MAXN],flag[MAXN],id[MAXN];
void dfs(int u, int fa, int poi)
{
    L[u]=++deep;
    id[deep]=u;
    flag[u]=poi;
    int siz=node[u].size();
    for(int i=0; i<siz; ++i)
    {
        int v=node[u][i];
        if(v==fa)continue;
        dfs(v,u,poi^1);
    }
    R[u]=deep;
}
/*
void build(int l, int r, int poi)
{
    if(l==r){lazy[0][poi]=lazy[1][poi]=val[id[l]];return;}
    int mid=(l+r)>>1;
    build(l,mid,poi<<1);
    build(mid+1,r,poi<<1^1);
}*/
void push_data(int poi)
{
    if(lazy[0][poi])
    {
        lazy[0][poi<<1]+=lazy[0][poi];
        lazy[0][poi<<1^1]+=lazy[0][poi];
    }
    if(lazy[1][poi])
    {
        lazy[1][poi<<1]+=lazy[1][poi];
        lazy[1][poi<<1^1]+=lazy[1][poi];
    }
    lazy[0][poi]=lazy[1][poi]=0;
}
void update(int l, int r, int a, int b, int poi, int f, int add)
{
    if(a<=l && r<=b){lazy[f][poi]+=add;lazy[f^1][poi]-=add;return;}
    push_data(poi);
    int mid=(l+r)>>1;
    if(mid>=a)update(l,mid,a,b,poi<<1,f,add);
    if(mid<b)update(mid+1,r,a,b,poi<<1^1,f,add);
}
int query(int l, int r, int poi, int f, int p)
{
    if(l==r)return lazy[f][poi];
    push_data(poi);
    int mid=(l+r)>>1;
    if(mid>=p)return query(l,mid,poi<<1,f,p);
    return query(mid+1,r,poi<<1^1,f,p);
}
int main()
{
    scanf("%d%d",&n,&m);
    index=0;
    for(int i=1; i<=n; ++i)
        scanf("%d",&val[i]);
    int a,b,c;
    for(int i=0; i<n-1; ++i)
    {
        scanf("%d%d",&a,&b);
      node[a].push_back(b);
      node[b].push_back(a);
    }
    deep=0;
    dfs(1,0,0);
//    build(1,n,1);
    for(int i=0; i<m; ++i)
    {
        scanf("%d%d",&a,&b);
        if(a==1)
        {
            scanf("%d",&c);
            update(1,n,L[b],R[b],1,flag[b],c);
        }
        else
            printf("%d\n",val[b]+query(1,n,1,flag[b],L[b]));
    }
    return 0;
}
/*

5 5
1 2 1 1 2
1 2
1 3
2 4
2 5
1 2 3
1 1 2
2 1
2 2
2 4

*/



树状数组:


//#include <bits/stdc++.h>
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define LL long long
#define bug cout<<"bug"<<endl
#define lowbit(a) a&(-a)
const int MAXN = 2e5+7;
int n,m,index;
int val[MAXN],lazy[2][MAXN<<2];
vector<int> node[MAXN];
int deep,L[MAXN],R[MAXN],flag[MAXN],id[MAXN];
void dfs(int u, int fa, int poi)
{
    L[u]=++deep;
    id[deep]=u;
    flag[u]=poi;
    int siz=node[u].size();
    for(int i=0; i<siz; ++i)
    {
        int v=node[u][i];
        if(v==fa)continue;
        dfs(v,u,poi^1);
    }
    R[u]=deep;
}
void add_data(int p, int f, int data)
{
    int i=p;
    while(i<=n)
    {
        lazy[f][i]+=data;
        lazy[f^1][i]-=data;
        i+=lowbit(i);
    }
}
int query(int p, int f)
{
    int i=p,ans=0;
    while(i>0)
    {
        ans+=lazy[f][i];
        i-=lowbit(i);
    }
    return ans;
}
int main()
{
    scanf("%d%d",&n,&m);
    index=0;
    for(int i=1; i<=n; ++i)
        scanf("%d",&val[i]);
    int a,b,c;
    for(int i=0; i<n-1; ++i)
    {
        scanf("%d%d",&a,&b);
        node[a].push_back(b);
        node[b].push_back(a);
    }
    deep=0;
    dfs(1,0,0);
    for(int i=0; i<m; ++i)
    {
        scanf("%d%d",&a,&b);
        if(a==1)
        {
            scanf("%d",&c);
            add_data(L[b],flag[b],c);
            add_data(R[b]+1,flag[b],-c);
        }
        else
            printf("%d\n",val[b]+query(L[b],flag[b]));
    }
    return 0;
}
/*

5 5
1 2 1 1 2
1 2
1 3
2 4
2 5
1 2 3
1 1 2
2 1
2 2
2 4

*/



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值