CodeForces - 383C Propagating tree (DFS序+线段树)

题意:

n个结点的树,以1为根,给出结点的权值。有两种操作:

        1.从某个结点开始使其权值 + v ,并将他的儿子结点 - v ,再将他的儿子的儿子结点 + v,...............,如此操作到叶子结点。

        2.查询某点的值

思路:

        显然,操作一是指 对深度奇偶性一致的子结点做 + ,不一致的做 - 。

        所以我们可以根据结点深度的奇偶性,通过DFS序建立两颗线段树。将操作一和二化为线段树区间修改,单点查询的操作。

        注意特判只有一个根结点的情况。

代码:

#include 
using namespace std;
#define ls l,mid,rt*2,k
#define rs mid+1,r,rt*2+1,k
#define sf rt,k
#define mi (l+r)/2
const int MAXN=2e5+7;
vector  edge[MAXN];
int n,m,a[MAXN];
int order[2][MAXN],depth[MAXN],in[2][MAXN],out[2][MAXN],cnt[2];
int ppp[2],tree[2][MAXN*4],lazy[2][MAXN*4];
int st,en,v;
void dfs(int pos,int dep){
    depth[pos]=dep;
    int k=dep%2;
    cnt[k]++;
    order[k][cnt[k]]=pos;
    in[k][pos]=cnt[k];
    in[!k][pos]=cnt[!k]+1;
    int len=edge[pos].size();
    for(int i=0;ien||ren||r


你可能感兴趣的:(—————数据结构—————,>树形转线形<,DFS序)