ZOJ 3686 A Simple Tree Problem(线段树)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ZOJ 3686 A Simple Tree Problem(线段树)相关的知识,希望对你有一定的参考价值。
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
#include<cstring> #include<cstdio> #include<iostream> #include<cmath> #include<vector> #include<algorithm> #define lc idx<<1 #define rc idx<<1|1 #define lson l,mid,lc #define rson mid+1,r,rc #define N 100010 using namespace std; int n,m; vector<int>G[N]; int L[N],R[N],id; struct Tree { int st; int one; } tree[N<<2]; void init() { for(int i=0; i<=n; i++) G[i].clear(); id=1; } void dfs(int fa) { L[fa]=id++; for(int i=0; i<G[fa].size(); i++) { dfs(G[fa][i]); } R[fa]=id-1; } void push_up(int idx) { tree[idx].one=tree[lc].one+tree[rc].one; } void push_down(int idx,int m) { if(tree[idx].st) { tree[lc].st^=1,tree[rc].st^=1; tree[idx].st=0; tree[lc].one=m-m/2-tree[lc].one; tree[rc].one=m/2-tree[rc].one; } } void build(int l,int r,int idx) { tree[idx].one=0; tree[idx].st=0; if(l==r)return; int mid=(l+r)>>1; build(lson); build(rson); } void update(int l,int r,int idx,int x,int y) { if(x<=l&&r<=y) { tree[idx].st^=1; tree[idx].one=r-l+1-tree[idx].one; return; } push_down(idx,r-l+1); int mid=(l+r)>>1; if(x<=mid)update(lson,x,y); if(y>mid) update(rson,x,y); push_up(idx); } int query(int l,int r,int idx,int x,int y) { if(x<=l&&r<=y) return tree[idx].one; push_down(idx,r-l+1); int mid=(l+r)>>1; int ans=0; if(x<=mid) ans+=query(lson,x,y); if(y>mid) ans+=query(rson,x,y); return ans; } int main() { //freopen("test.in","r",stdin); while(~scanf("%d%d",&n,&m)) { init(); int fa; for(int i=2; i<=n; i++) { scanf("%d",&fa); G[fa].push_back(i); } dfs(1); build(1,n,1); char c[3]; int rt; while(m--) { scanf("%s%d",c,&rt); if(c[0]==‘o‘) { update(1,n,1,L[rt],R[rt]); continue; } printf("%d\n",query(1,n,1,L[rt],R[rt])); } printf("\n"); } return 0; }
以上是关于ZOJ 3686 A Simple Tree Problem(线段树)的主要内容,如果未能解决你的问题,请参考以下文章