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. leetcode140 Word Break II

    思路: 直接爆搜会超时,需要使用记忆化搜索.使用map把已经计算过的情况记录下来,避免重复计算. 实现: class Solution { public: vector<string> w ...

  2. IE兼容只读模式

    表单input具有只读模式属性,一般来说,一般的浏览器都支持该属性,即readyonly,但IE不支持,只能寻找其兼容性. 第一种:unselectable='on' <input id=&qu ...

  3. uvm_base——打好你的基础

    uvm_base 是个很有意思的文件,这是UVM很巧妙的设计,将所有在base中包含的文件都包含在uvm_base.svh, 这样很方便管理各个文件直接的关系,而且还可以看出一些我之前没看过的东西,比 ...

  4. echarts getAttribute”的值: 对象为 null 或未定义 错误解决方法,

    echarts.js引用放在head中或者放在body中HTML代码的前面了,造成加载时阻塞后面的html. 解决方法就是将echarts.js的引用放在</body>之前就可以了,完美解 ...

  5. ajax上传文件以及使用中常见问题处理

    <script src="/scripts/ajaxfileupload.js"></script> <script src="/scrip ...

  6. shiro 配置拦截规则之后css和js等失效

    使用shiro作为平台的权限管理工具,shiro的配置文件如下: package com.ros.config; import java.util.LinkedHashMap;import java. ...

  7. 通过90行代码学会HTML5 WebSQL的4种基本操作

    Web SQL数据库API是一个独立的规范,在浏览器层面提供了本地对结构化数据的存储,已经被很多现代浏览器支持了. 我们通过一个简单的例子来了解下如何使用Web SQL API在浏览器端创建数据库表并 ...

  8. 你是猴子请来的逗比么!IT跳槽大事件

       3月招聘大战早已硝烟四起,互联网职场摇身一变成了跳蚤市场,猎头们告诉跳蚤们,跳不跳不是不问题,往哪儿跳才是重点,跳对了高薪期权都如过眼云烟.不过小编不得不说,劳资最痛恨那些跳槽的人啦!就因为加班 ...

  9. 10048 - Audiophobia (Floyd)

    Floyd的变形,本质是动态规划,路径分成的两个部分中取最大值作为该路径的答案,在所有可行路径之中选一个最小值. #include<bits/stdc++.h> using namespa ...

  10. 多维的vector定义和初始化

    vector<vector<int> >vv(3, vector<int>(4));//这里,两个“>”间的空格是不可少的 将构造一个二维向量vv,它含有三个 ...