ZOJ 3686 A Simple Tree Problem

来源:互联网 发布:600831广电网络 编辑:程序博客网 时间:2024/05/16 14:39

A Simple Tree Problem

Time Limit: 3 Seconds      Memory Limit: 65536 KB

Given a rooted tree, each node has a boolean (0 or 1) labeled on it. Initially, all the labels are 0.

We define this kind of operation: given a subtree, negate all its labels.

And we want to query the numbers of 1's of a subtree.

Input

Multiple test cases.

First line, two integer N and M, denoting the numbers of nodes and numbers of operations and queries.(1<=N<=100000, 1<=M<=10000)

Then a line with N-1 integers, denoting the parent of node 2..N. Root is node 1.

Then M lines, each line are in the format "o node" or "q node", denoting we want to operate or query on the subtree with root of a certain node.

Output

For each query, output an integer in a line.

Output a blank line after each test case.

Sample Input

3 21 1o 2q 1

Sample Output

1

Author: CUI, Tianyi
Contest: ZOJ Monthly, March 2013


先DFS搜索出每个结点所控制的范围,然后就可以用线段树了。


#include <iostream>#include <cstdio>#include <cstring>#include <vector>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;vector<int> g[200010];int n,m,id;const int maxn=200010;struct Interval{    int from,to;}I[200010];void dfs(int node){    I[node].from=id;    id++;    int t=g[node].size();    for(int i=0;i<t;i++)    {        dfs(g[node][i]);    }    I[node].to=id-1;}int m0[maxn<<2],m1[maxn<<2],xxo[maxn<<2];void push_up(int rt){    m0[rt]=m0[rt<<1]+m0[rt<<1|1];    m1[rt]=m1[rt<<1]+m1[rt<<1|1];}void push_down(int rt){    if(xxo[rt])    {        xxo[rt<<1]^=1; xxo[rt<<1|1]^=1;        swap(m0[rt<<1|1],m1[rt<<1|1]);swap(m0[rt<<1],m1[rt<<1]);        xxo[rt]=0;    }}void build(int l,int r,int rt){    xxo[rt]=0;m0[rt]=0;m1[rt]=0;    if(l==r)    {        m0[rt]=1; m1[rt]=0;        return ;    }    int m=(l+r)>>1;    push_down(rt);    build(lson); build(rson);    push_up(rt);}void update(int L,int R,int l,int r,int rt){    if(L<=l&&r<=R)    {        xxo[rt]^=1;        swap(m0[rt],m1[rt]);        return ;    }    int m=(l+r)>>1;    push_down(rt);    if(L<=m) update(L,R,lson);    if(R>m) update(L,R,rson);    push_up(rt);}int query(int L,int R,int l,int r,int rt){    if(L<=l&&r<=R)    {        push_down(rt);        return m1[rt];    }    int m=(l+r)>>1,ret=0;    push_down(rt);    if(L<=m) ret+=query(L,R,lson);    if(R>m) ret+=query(L,R,rson);    push_up(rt);    return ret;}int main(){    while(scanf("%d%d",&n,&m)!=EOF)    {        for(int i=0;i<=n+10;i++) g[i].clear();        memset(m0,0,sizeof(m0));        memset(m1,0,sizeof(m1));        memset(xxo,0,sizeof(xxo));        for(int i=2;i<=n;i++)        {            int a;            scanf("%d",&a);            g[a].push_back(i);        }        id=1;        dfs(1);        build(1,n,1);        while(m--)        {            char cmd[5]; int a;            scanf("%s%d",cmd,&a);            if(cmd[0]=='o')   update(I[a].from,I[a].to,1,n,1);            else if(cmd[0]=='q')   printf("%d\n",query(I[a].from,I[a].to,1,n,1));        }        putchar(10);    }    return 0;}



原创粉丝点击