ZOJ 3686 A Simple Tree Problem
来源:互联网 发布:600831广电网络 编辑:程序博客网 时间:2024/05/16 14:39
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;}
- ZOJ 3686 A A Simple Tree Problem
- zoj 3686 A Simple Tree Problem
- ZOJ 3686 : A Simple Tree Problem
- zoj 3686 (a simple tree problem)
- ZOJ 3686 A Simple Tree Problem
- ZOJ 3686 A Simple Tree Problem
- ZOJ 3686 A Simple Tree Problem (线段树)
- ZOJ 3686 A Simple Tree Problem (线段树)
- zoj 3686 A Simple Tree Problem(dfs+线段树)
- ZOJ 3686-A Simple Tree Problem (DFS+线段树)
- ZOJ 3686 A Simple Tree Problem(线段树)
- ZOJ 3686 A Simple Tree Problem DFS+线段树(区间取反)
- zoj 3686 A Simple Tree Problem (经典,利用dfs序维护树)
- ZOJ 3686 A Simple Tree Problem(树转线段树+线段树区间更新)
- ZOJ 3686 A Simple Tree Problem(将对树的操作转化成区间=>线段树)
- ZOJ Monthly, March 2013 A题 A Simple Tree Problem(线段树)#zh
- BNU A Simple Tree Problem 线段树
- ZOJ3696-A Simple Tree Problem 线段树
- 学习代码及算法(未完待续,不定时更新)
- 快速把web项目部署到weblogic上
- 分页高级查询步骤
- android-Viewpager
- 经典排序算法设计与分析(插入排序、冒泡排序、选择排序、shell排序、快速排序、堆排序、分配排序、基数排序、桶排序、归并排序)
- ZOJ 3686 A Simple Tree Problem
- Hadoop集群测试第一步:在虚拟机中安装Linux
- Vertex Atrributes
- SQLSERVER2005调试存储过程跟函数
- 提升HBase写性能
- Java 并发编程实战学习笔记——寻找可强化的并行性
- seo关键词优化方法用关键词无布局才能让网站处不在
- 关于ios XCode hangs at "Attaching to (app name)"
- 傅里叶变换:MP3、JPEG和Siri背后的数学