标签:编号 amp 线段树 class max 个数 targe 查询 com
http://www.cnblogs.com/lkcc/p/7684077.html
题意:给你一棵树,每个结点 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
标签:编号 amp 线段树 class max 个数 targe 查询 com
原文地址:http://www.cnblogs.com/lkcc/p/7726088.html