ZOJ_3686_A Simple Tree Problem(线段树成端更新)

来源:互联网 发布:淘宝pc端是在哪里 编辑:程序博客网 时间:2024/05/23 01:56

题型:数据结构


题意:

给一棵树,初始每个节点的值为0,给出m个操作:

(1)o Node:将以节点Node为根的子树的所有节点的值取反。

(2)q Node:查询以节点Node为根的子树中1的节点的个数。


分析:

       按照中序遍历,给每个节点标上id,这样,可以很快的求出某个点作为根节点所构成的子树所包括的范围,即子树的最右下节点。

       这样就可以构造出线段树了,每个节点存着对应管辖范围内1的个数,当然,由于需要进行成段更新,每个节点需要设置一个延迟标记。

       对于将子树中所有的节点取反,就是用子树的节点数减去当前的1的个数。


代码:

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#define mt(a,b) memset(a,b,sizeof(a))#define lrrt int L,int R,int rt#define iall 1,n,1#define imid int mid=(L+R)>>1;#define lson L,mid,rt<<1#define rson mid+1,R,rt<<1|1using namespace std;const int M = 123456;struct T{    int val,lazy;}tree[M<<2];void pushup(int rt){    tree[rt].val = tree[rt<<1].val + tree[rt<<1|1].val;}void pushdown(int mid,lrrt){    if(tree[rt].lazy){        tree[rt<<1].val = mid - L + 1 - tree[rt<<1].val;        tree[rt<<1].lazy ^= 1;        tree[rt<<1|1].val = R - mid - tree[rt<<1|1].val;        tree[rt<<1|1].lazy ^= 1;        tree[rt].lazy = 0;    }}void update(int x,int y,lrrt){    if(x<=L && R<=y){        tree[rt].val = R - L + 1 - tree[rt].val;        tree[rt].lazy ^= 1;        return;    }    imid;    pushdown(mid,L,R,rt);    if(mid >= x) update(x,y,lson);    if(mid < y) update(x,y,rson);    pushup(rt);}int query(int x,int y,lrrt){    if(x<=L && R <=y){        return tree[rt].val;    }    imid;    pushdown(mid,L,R,rt);    int ans = 0;    if(mid >= x) ans += query(x,y,lson);    if(mid < y)  ans += query(x,y,rson);    return ans;}struct E{    int u,v,next;}e[M];int le,head[M];void init(){    le = 0;    mt(head,-1);}void add(int u,int v){    e[le].u = u;    e[le].v = v;    e[le].next = head[u];    head[u] = le++;}struct G{    int l,r;}node[M];int Index;void dfs(int u){    node[u].l = ++Index;    for(int i=head[u];~i;i=e[i].next){        dfs(e[i].v);    }    node[u].r = Index;}int main() {    int n,m,x;    while(~scanf("%d%d",&n,&m)){        init();        for(int i=2;i<=n;i++){            scanf("%d",&x);            add(x,i);        }        Index = 0;        dfs(1);        mt(tree,0);        char op[5];        while(m--){            scanf("%s%d",op,&x);            if(op[0] == 'o'){                update(node[x].l,node[x].r,iall);            }            else{                printf("%d\n",query(node[x].l,node[x].r,iall));            }        }        puts("");    }    return 0;}


0 0
原创粉丝点击