zoj 3686 - A Simple Tree Problem (dfs序+線段樹區間更新)
阿新 • • 發佈:2018-11-22
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.
InputMultiple test cases.
First line, two integer N
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.
For each query, output an integer in a line.
Output a blank line after each test case.
Sample Input3 2 1 1 o 2 q 1Sample Output
1
好久沒寫線段樹區間更新了,找個裸題練練手
#include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> #include <vector> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int maxn = 1e5+5; vector<int> p[maxn]; int n,m,tol; int siz[maxn],idx[maxn]; int tree[maxn<<2],lazy[maxn<<2]; void build(int l,int r,int rt) { if(l==r) { tree[rt] = 0; lazy[rt] = 0; return ; } int m = (l+r)>>1; build(lson); build(rson); tree[rt] = tree[rt<<1]+tree[rt<<1|1]; lazy[rt] = 0; } int dfs(int u) { int ans = 0; idx[u] = ++tol; for(int i=0; i<p[u].size(); i++) { int v = p[u][i]; ans += dfs(v)+1; } return siz[u] = ans; } void pushDown(int rt,int l,int r) { if(lazy[rt]%2) { int m = (l+r)>>1; lazy[rt<<1]++; lazy[rt<<1|1]++; tree[rt<<1] = (m-l+1) - tree[rt<<1]; tree[rt<<1|1] = (r-m) - tree[rt<<1|1]; lazy[rt] = 0; } } int query(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R) { return tree[rt]; } pushDown(rt,l,r); int m = (l+r)>>1; int ret = 0; if(L<=m) ret += query(L,R,lson); if(R>m) ret += query(L,R,rson); tree[rt] = tree[rt<<1]+tree[rt<<1|1]; return ret; } void update(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R) { lazy[rt]++; tree[rt] = (r-l+1)-tree[rt]; return; } pushDown(rt,l,r); int m = (l+r)>>1; if(L<=m) update(L,R,lson); if(R>m) update(L,R,rson); tree[rt] = tree[rt<<1]+tree[rt<<1|1]; } int main() { while(scanf("%d%d",&n,&m)!=EOF) { tol = 0; for(int i=1; i<=n; i++) p[i].clear(); build(1,n,1); for(int i=2; i<=n; i++) { int v; scanf("%d",&v); p[v].push_back(i); } dfs(1); while(m--) { char s[2]; int u; scanf("%s%d",s,&u); if(s[0]=='o') { update(idx[u],idx[u]+siz[u],1,n,1); } else if(s[0]=='q') { printf("%d\n",query(idx[u],idx[u]+siz[u],1,n,1)); } } puts(""); } return 0; }