A Simple Tree Problem

Time Limit: 3000ms
Memory Limit: 65536KB

This problem will be judged on ZJU. Original ID: 3686
64-bit integer IO format: %lld      Java class name: Main

Type:

None

 

None

Graph Theory

2-SAT

Articulation/Bridge/Biconnected Component

Cycles/Topological Sorting/Strongly Connected Component

Shortest Path

Bellman Ford

Dijkstra/Floyd Warshall

Euler Trail/Circuit

Heavy-Light Decomposition

Minimum Spanning Tree

Stable Marriage Problem

Trees

Directed Minimum Spanning Tree

Flow/Matching

Graph Matching

Bipartite Matching

Hopcroft–Karp Bipartite Matching

Weighted Bipartite Matching/Hungarian Algorithm

Flow

Max Flow/Min Cut

Min Cost Max Flow

DFS-like

Backtracking with Pruning/Branch and Bound

Basic Recursion

IDA* Search

Parsing/Grammar

Breadth First Search/Depth First Search

Advanced Search Techniques

Binary Search/Bisection

Ternary Search

Geometry

Basic Geometry

Computational Geometry

Convex Hull

Pick's Theorem

Game Theory

Green Hackenbush/Colon Principle/Fusion Principle

Nim

Sprague-Grundy Number

Matrix

Gaussian Elimination

Matrix Exponentiation

Data Structures

Basic Data Structures

Binary Indexed Tree

Binary Search Tree

Hashing

Orthogonal Range Search

Range Minimum Query/Lowest Common Ancestor

Segment Tree/Interval Tree

Trie Tree

Sorting

Disjoint Set

String

Aho Corasick

Knuth-Morris-Pratt

Suffix Array/Suffix Tree

Math

Basic Math

Big Integer Arithmetic

Number Theory

Chinese Remainder Theorem

Extended Euclid

Inclusion/Exclusion

Modular Arithmetic

Combinatorics

Group Theory/Burnside's lemma

Counting

Probability/Expected Value

Others

Tricky

Hardest

Unusual

Brute Force

Implementation

Constructive Algorithms

Two Pointer

Bitmask

Beginner

Discrete Logarithm/Shank's Baby-step Giant-step Algorithm

Greedy

Divide and Conquer

Dynamic Programming

Tag it!

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

题目大意:有棵根节点为1的树,共有n个节点。有m次询问。第二行为从2--->n各个节点对应的父亲节点编号。下面的m行是询问,o  ai表示将节点为ai的子树所有节点的值进行异或即0变1,1变0。q ai表示询问目前该子树的节点的和值为多少。

解题思路:其实这个题目重点在如何将多子树转化成线段树进行操作。我们如果重新将树编号,那么可以让每个节点对应一段区间。从根节点1开始深搜,编号为1,每当搜到一个节点,就让编号的值加1,让这个编号等于该节点的区间左端点,等把该节点的所有子节点访问完后,将这时的编号赋值给该节点的区间右端点。这时这个区间内的所有节点都是该节点的子节点。  后边就是区间更新的问题了。

#include<bits/stdc++.h>
using namespace std;
#define mid (L+R)/2
#define lson rt*2,L,mid
#define rson rt*2+1,mid+1,R
const int maxn=1e5+50;
vector<int>G[maxn];
int Lt[maxn],Rt[maxn];
int sumv[maxn*4],lazy[maxn*4];
int n,cn;
void dfs(int u){
Lt[u]=++cn;
int v;
for(int i=0;i<G[u].size();i++){
v=G[u][i];
dfs(v);
}
Rt[u]=cn;
}
void build(int rt,int L,int R){
sumv[rt]=lazy[rt]=0;
if(L==R)
return ;
build(lson);
build(rson);
}
void PushDown(int rt,int L,int R){
if(lazy[rt]){
lazy[rt*2]^=1;
lazy[rt*2+1]^=1;
sumv[rt*2]=(mid-L+1)-sumv[rt*2];
sumv[rt*2+1]=(R-mid)-sumv[rt*2+1];
lazy[rt]=0;
}
}
void PushUp(int rt){
sumv[rt]=sumv[rt*2]+sumv[rt*2+1];
}
void update(int rt,int L,int R,int l_ran,int r_ran){
if(l_ran<=L&&R<=r_ran){
lazy[rt]^=1;
sumv[rt]=R-L+1-sumv[rt];
return ;
}
PushDown(rt,L,R);
if(l_ran<=mid){
update(lson,l_ran,r_ran);
}
if(r_ran>mid){
update(rson,l_ran,r_ran);
}
PushUp(rt);
}
int query(int rt,int L,int R,int l_ran,int r_ran){
if(l_ran<=L&&R<=r_ran){
return sumv[rt];
}
int ret=0;
PushDown(rt,L,R); //lazy下放
if(l_ran<=mid){
ret+=query(lson,l_ran,r_ran);
}
if(r_ran>mid){
ret+=query(rson,l_ran,r_ran);
}
return ret;
}
int main(){
char s[4];
int m,subt,a,res;
while(scanf("%d%d",&n,&m)!=EOF){
build(1,1,n);
for(int i=0;i<=n;i++)
G[i].clear();
for(int i=2;i<=n;i++){
scanf("%d",&a);
G[a].push_back(i);
}
cn=0;
dfs(1);
for(int i=0;i<m;i++){
scanf("%s%d",s,&subt);
if(s[0]=='o'){
update(1,1,n,Lt[subt],Rt[subt]);
}else{
res=query(1,1,n,Lt[subt],Rt[subt]);
printf("%d\n",res);
}
}printf("\n"); }
return 0;
} /*
6 5
1 2 1 4 4
o 4
q 4
q 5
q 6
q 1
*/

  

BNU 28887——A Simple Tree Problem——————【将多子树转化成线段树+区间更新】的更多相关文章

  1. POJ.3468 A Simple Problem with Integers(线段树 区间更新 区间查询)

    POJ.3468 A Simple Problem with Integers(线段树 区间更新 区间查询) 题意分析 注意一下懒惰标记,数据部分和更新时的数字都要是long long ,别的没什么大 ...

  2. poj 3468 A Simple Problem with Integers (线段树区间更新求和lazy思想)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 75541   ...

  3. POJ 3468:A Simple Problem with Integers(线段树区间更新模板)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 141093 ...

  4. poj3468 A Simple Problem with Integers(线段树区间更新)

    https://vjudge.net/problem/POJ-3468 线段树区间更新(lazy数组)模板题 #include<iostream> #include<cstdio&g ...

  5. POJ 3468A Simple Problem with Integers(线段树区间更新)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 112228 ...

  6. POJ-3468-A Simple Problem with Integers(线段树 区间更新 区间和)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 139191 ...

  7. POJ 3468 A Simple Problem with Integers(线段树区间更新区间查询)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 92632   ...

  8. [POJ] 3468 A Simple Problem with Integers [线段树区间更新求和]

    A Simple Problem with Integers   Description You have N integers, A1, A2, ... , AN. You need to deal ...

  9. 暑期训练狂刷系列——poj 3468 A Simple Problem with Integers (线段树+区间更新)

    题目连接: http://poj.org/problem?id=3468 题目大意: 给出n个数,有两种操作: 1:"C a b c",[a,b]中的每一个数都加上c. 2:&qu ...

随机推荐

  1. C语言/C++编程学习:C语言环境设置

    C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构.C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现 ...

  2. excel文档中嵌入对象(excel、word等)

    //测试环境office2016.office365 string InsertPath= @"E:\\新建文件夹\\2.xls";//插入的文档路径 string openfil ...

  3. Node简单服务器开发

    运用的知识:http,fs,get,post 接口定义:/user?act=reg$user=aaa&pass=bbb后台返回格式:{"ok":false,"ms ...

  4. eclipse 开发hbase 环境准备

    修改开发机的host文件:

  5. git配置本地环境(phpstudy/tortoisegit/git等)

    1.下载安装phpstudy 2.下载安装git 下载地址:https://git-scm.com/downloads 3.下载安装tortoisegit,电脑64位就下载这个,如图: 4.下载安装“ ...

  6. 【python】Python任务调度模块 – APScheduler

    APScheduler是一个Python定时任务框架,使用起来十分方便.提供了基于日期.固定时间间隔以及crontab类型的任务,并且可以持久化任务.并以daemon方式运行应用.目前最新版本为3.0 ...

  7. 【SSO单点系列】(4):CAS4.0 SERVER登录后用户信息的返回

    接着上一篇,在上一篇中我们描述了怎么在CAS SERVER登录页上添加验证码,并进行登录.一旦CAS SERVER验证成功后,我们就会跳转到客户端中去.跳转到客户端去后,大家想一想,客户端总要获取用户 ...

  8. 百度编辑器 Ueditor使用记录

    Ueditor官网: http://fex.baidu.com/ueditor/#dev-bale_width_grunt UeditorAPI文档: https://ueditor.baidu.co ...

  9. Opencv博文收藏列表

    opencv识别二维码:https://blog.csdn.net/jia20003/article/details/77348170 opencv视频:http://www.opencv.org.c ...

  10. SQL语句之表操作

    SQL语句系列 1.SQL语句之行操作 2.SQL语句之表操作 3.SQL语句之数据库操作 4.SQL语句之用户管理 写在前面 在上一篇博文里面我整理了“行”级别的操作,分别是“增(insert).删 ...