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 2
1 1
o 2
q 1

Sample Output

1

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

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

ZOJ 3686 A Simple Tree Problem的更多相关文章

  1. ZOJ 3686 A Simple Tree Problem(线段树)

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

  2. zoj 3686 A Simple Tree Problem (线段树)

    Solution: 根据树的遍历道的时间给树的节点编号,记录下进入节点和退出节点的时间.这个时间区间覆盖了这个节点的所有子树,可以当做连续的区间利用线段树进行操作. /* 线段树 */ #pragma ...

  3. BNU 28887——A Simple Tree Problem——————【将多子树转化成线段树+区间更新】

    A Simple Tree Problem Time Limit: 3000ms Memory Limit: 65536KB This problem will be judged on ZJU. O ...

  4. xtu数据结构 I. A Simple Tree Problem

    I. A Simple Tree Problem Time Limit: 3000ms Memory Limit: 65536KB 64-bit integer IO format: %lld     ...

  5. 2014 Super Training #9 F A Simple Tree Problem --DFS+线段树

    原题: ZOJ 3686 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3686 这题本来是一个比较水的线段树,结果一个ma ...

  6. ZOJ-3686 A Simple Tree Problem 线段树

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3686 题意:给定一颗有根树,每个节点有0和1两种值.有两种操作: ...

  7. BZOJ 3489: A simple rmq problem

    3489: A simple rmq problem Time Limit: 40 Sec  Memory Limit: 600 MBSubmit: 1594  Solved: 520[Submit] ...

  8. hdu4976 A simple greedy problem. (贪心+DP)

    http://acm.hdu.edu.cn/showproblem.php?pid=4976 2014 Multi-University Training Contest 10 1006 A simp ...

  9. hdu 1757 A Simple Math Problem (乘法矩阵)

    A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

随机推荐

  1. 最强 Android Studio 使用小技巧和快捷键

    写在前面 本文翻译自 Android Studio Tips by Philippe Breault,一共收集了62个 Android Studio 使用小技巧和快捷键. 根据这些小技巧的使用场景,本 ...

  2. C#简单的对象交互

    在对象的世界里,一切皆为对象;对象与对象相互独立,互不干涉,但在一定外力的作用下对象开始共同努力 对象交互的实例 电视机大家都有吧,依照万物皆对象的思维模式来看,电视机可以是一个类,然后电视机有一些基 ...

  3. 21-Python-Django进阶补充篇

    1. 路由部分补充 1.1 默认值 url: url(r'^index/', views.index, {'name': 'root'}), views: def index(request,name ...

  4. [LeetCode] Find K Pairs with Smallest Sums 找和最小的K对数字

    You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k. Define ...

  5. [LeetCode] Remove Linked List Elements 移除链表元素

    Remove all elements from a linked list of integers that have value val. Example Given: 1 --> 2 -- ...

  6. python读取excel一例-------从工资表逐行提取信息

    在工作中经常要用到python操作excel,比如笔者公司中一个人事MM在发工资单的时候,需要从几百行的excel表中逐条的粘出信息,然后逐个的发送到员工的邮箱中.人事MM对此事不胜其烦,终于在某天请 ...

  7. 【ios开发】UITableViewCell的重用

    移动开发需要解决的一个问题就是资源稀缺的问题.多数情况下是内存问题. 虽然现在的手机都号称大内存,高配置.但是移动app所占用的资源也在跟着不断膨胀, 也是造成内存不足的主要原因. 在前面的例子中,还 ...

  8. C#设计模式(2)——简单工厂模式

    一.概念:简单工厂模式(Simple Factory Pattern)属于类的创新型模式,又叫静态工厂方法模式(Static FactoryMethod Pattern),是通过专门定义一个类来负责创 ...

  9. redis-内存异常 Redis is configured to save RDB snapshots解决

    连接reids获取数据时提示 Redis is configured to save RDB snapshots, but is currently not able to persist on di ...

  10. 微软 消息队列 MessageQueue 简单使用

    1.在服务电脑上打开 消息队列 ①进入控制面板>程序>启用或关闭windows功能 ②将需要的勾选(我自己全选了哈哈哈) ③我的电脑 右键 打开管理 见到消息队列 在专用队列上新建专用队列 ...