I. A Simple Tree Problem

Time Limit: 3000ms
Memory Limit: 65536KB

64-bit integer IO format: %lld      Java class name: Main

 

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
 解题:利用dfs记录时间戳,也就是记录区间长度,恰好的包含关系,为建立线段树带来很大的方便,不需要建立N棵线段树,但以某一点为根节点的字孩子区间一定是父节点的区间的子区间。这样好的性质,恰好可以映射到线段树上。。。。。
 
 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <climits>
#include <algorithm>
#include <cmath>
#define LL long long
#define INF 0x3f3f3f
using namespace std;
const int maxn = ;
int n,m,id;
vector<int>g[maxn];
int len[maxn<<],cnt[maxn<<],mark[maxn<<];
struct node{
int lt,rt;
}tree[maxn<<];
void dfs(int u){
tree[u].lt = ++id;
for(int i = ; i < g[u].size(); i++){
dfs(g[u][i]);
}
tree[u].rt = id;
}
void build(int lt,int rt,int v){
cnt[v] = mark[v] = ;
len[v] = rt-lt+;
if(lt == rt) return;
int mid = (lt+rt)>>;
build(lt,mid,v<<);
build(mid+,rt,v<<|);
}
void push_down(int v){
if(mark[v]){
cnt[v<<] = len[v<<]-cnt[v<<];
mark[v<<] ^= ;
cnt[v<<|] = len[v<<|]-cnt[v<<|];
mark[v<<|] ^= ;
mark[v] = ;
}
}
void update(int x,int y,int lt,int rt,int v){
if(lt >= x && rt <= y){
cnt[v] = len[v] - cnt[v];
if(lt == rt) return;
mark[v] ^= ;
return;
}
push_down(v);
int mid = (lt+rt)>>;
if(x <= mid) update(x,y,lt,mid,v<<);
if(y > mid) update(x,y,mid+,rt,v<<|);
cnt[v] = cnt[v<<]+cnt[v<<|];
}
int query(int x,int y,int lt,int rt,int v){
int ans = ;
if(x <= lt && rt <= y){
return cnt[v];
}
push_down(v);
int mid = (lt+rt)>>;
if(x <= mid) ans += query(x,y,lt,mid,v<<);
if(y > mid) ans += query(x,y,mid+,rt,v<<|);
return ans;
}
int main(){
int i,temp;
char s;
while(~scanf("%d%d",&n,&m)){
for(i = ; i <= n; i++)
g[i].clear();
for(i = ; i <= n; i++){
scanf("%d",&temp);
g[temp].push_back(i);
}
id = ;
dfs();
build(,n,);
while(m--){
cin>>s>>temp;
if(s == 'o'){
update(tree[temp].lt,tree[temp].rt,,n,);
}else cout<<query(tree[temp].lt,tree[temp].rt,,n,)<<endl;
}
cout<<endl;
}
return ;
}

xtu数据结构 I. A Simple Tree Problem的更多相关文章

  1. ZOJ 3686 A Simple Tree Problem

    A Simple Tree Problem Time Limit: 3 Seconds      Memory Limit: 65536 KB Given a rooted tree, each no ...

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

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

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

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

  4. 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 ...

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

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

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

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

  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. #113. 【UER #2】手机的生产

    链接:http://uoj.ac/problem/113 由于电信技术的发展,人人都可以通过手机互相联系. 有一位电信大佬最近想生产一大批手机,然而从生产线上一台一台地生产实在太慢了,于是他想出了一个 ...

  2. 前端页面,使用 dom 鼠标拖拽画一个矩形和监听键盘

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  3. Java中的if-else语句——通过示例学习Java编程(7)

      作者:CHAITANYA SINGH 来源:https://www.koofun.com/pro/kfpostsdetail?kfpostsid=18 当我们需要根据一个条件执行一组语句时,我们需 ...

  4. FPGA的嵌入式RAM

    FPGA中的嵌入式RAM分为两种:专用的BRAM和分布是RAM(用LUT实现的).这两种RAM又可以配置成单端口和双端口的RAM和ROM.双端口RAM又可以根据读写地址是否在同一块分为Double P ...

  5. shell中的-z

    -z 字符串为"null",即是指字符串长度为零.

  6. COGS 2688. 鱼的感恩

    ★   输入文件:fool.in   输出文件:fool.out   简单对比时间限制:1 s   内存限制:256 MB [题目描述] 从前有一个渔夫抓到了一条特别的鱼,放走了. 渔夫再次抓到了这条 ...

  7. codevs 2059 逃出克隆岛

     时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题目描述 Description oi小组的yh酷爱玩魔兽rpg,每天都会在u9搜索最新的rpg地图. 今天,他 ...

  8. Install your Application into RaspberryPi2 and automatically start up

    如何安装和卸载应用程序到RaspberryPi2? 如何配置应用程序在RaspberryPi2开机后自动启动? How to install your app into RaspberryPi2? H ...

  9. Java动态代理之InvocationHandler最简单的入门教程

    网上关于Java的动态代理,Proxy和InvocationHandler这些概念有讲解得非常高深的文章.其实这些概念没有那么复杂.现在咱们通过一个最简单的例子认识什么是InvocationHandl ...

  10. python实现微信打飞机游戏(by crossin)

    # -*- coding: utf-8 -*- import pygame from sys import exit import random pygame.init() screen = pyga ...