codefroces 877E - Danil and a Part-time Job
Posted 黑.白
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codefroces 877E - Danil and a Part-time Job相关的知识,希望对你有一定的参考价值。
http://codeforces.com/contest/877/problem/E
题意:给你一棵树,每个结点 0 、 1 标记。有二种操作( 查询某个结点及其子结点 1 的个数、将某个结点及其子结点的标记取反)。
题解:线段树
w[i] 表示 i 结点在线段树上对应的编号, End[i] 表示 i 结点及其子结点在线段树上编号最大的结点编号
这样 i 结点及其子结点就可以在线段树上用连续的编号 [ w[i], End[i] ] 表示。
int w[MAXN]; int End[MAXN], END = 0; void dfs(int id, int pr) { w[id] = ++END; for(int i = head[id]; ~i; i = edge[i].next) { int to = edge[i].to; if(to == pr) continue; dfs(to, id); } End[id] = END; }
AC代码
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #define lson id<<1,l,mid #define rson id<<1|1,mid+1,r using namespace std; const int MAXN = 200000+10; int n; int a[MAXN]; struct node { int to, next; node(){ } node(int to, int next) : to(to), next(next){ } }edge[2*MAXN]; int head[MAXN], alledge; void init() { memset(head, 0xff, sizeof(head)); alledge = 0; } void addedge(int x, int y) { edge[alledge] = node(y, head[x]); head[x] = alledge++; edge[alledge] = node(x, head[y]); head[y] = alledge++; } int w[MAXN]; int End[MAXN], END = 0; void dfs(int id, int pr) { w[id] = ++END; for(int i = head[id]; ~i; i = edge[i].next) { int to = edge[i].to; if(to == pr) continue; dfs(to, id); } End[id] = END; } struct treenode { int num; int flag; }tree[MAXN<<2]; void build_tree(int id, int l, int r) { if(l==r) { tree[id].num = a[l]; tree[id].flag = 0; return ; } int mid = l+r>>1; build_tree(lson); build_tree(rson); tree[id].num = tree[id<<1].num+tree[id<<1|1].num; } void update(int id, int l, int r) { tree[id].num = r-l+1-tree[id].num; tree[id].flag = !tree[id].flag; } void update(int id, int l, int r, int left, int right) { if(l==left && r==right) { tree[id].num = r-l+1-tree[id].num; tree[id].flag = !tree[id].flag; return ; } int mid = l+r>>1; if( tree[id].flag ) { update(lson); update(rson); tree[id].flag = 0; } if(right <= mid) { update(lson, left, right); } else if(left > mid) { update(rson, left, right); } else { update(lson, left, mid); update(rson, mid+1, right); } tree[id].num = tree[id<<1].num+tree[id<<1|1].num; } int query(int id, int l, int r, int left, int right) { if(l==left && r==right) { return tree[id].num; } int mid = l+r>>1; if( tree[id].flag ) { update(lson); update(rson); tree[id].flag = 0; } if(right <= mid) { return query(lson, left, right); } else if(left > mid) { return query(rson, left, right); } else { return query(lson, left, mid) + query(rson, mid+1, right); } } int main (void) { ios::sync_with_stdio(false); init(); cin >> n; for(int i = 2; i <= n; ++i) { int x; cin >> x; addedge(x, i); } dfs(1, -1); for(int i = 1; i <= n; ++i) { int x; cin >> x; a[w[i]] = x; } build_tree(1, 1, n); int q; cin >> q; while(q--) { string c; int x; cin >> c >> x; if( c == "pow") update(1, 1, n, w[x], End[x]); else cout<<query(1, 1, n, w[x], End[x])<<endl; } return 0; }
以上是关于codefroces 877E - Danil and a Part-time Job的主要内容,如果未能解决你的问题,请参考以下文章
877E - Danil and a Part-time Job(dfs序+线段树)
Codeforces 877E - Danil and a Part-time Job 线段树+dfs序
CF877E Danil and a Part-time Job 线段树维护dfs序
Codeforces Round #442 (Div. 2) 877E - Danil and a Part-time Job dfs序+线段树