zoj 3686 A Simple Tree Problem
2013-05-16 20:57
330 查看
题意就是给你一颗树。初始时每个节点的值都为0,现在有两种操作,‘o’操作是将以节点i为根的子树的每个节点取反,即0变1,1变0.‘q’操作是求以节点i为根的子树中1的个数。
方法主要是给每个节点分配一个区间,是这个区间的节点都是它的子节点。然后就是线段树的经典操作啦。
AC Code
方法主要是给每个节点分配一个区间,是这个区间的节点都是它的子节点。然后就是线段树的经典操作啦。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define maxn 100005 struct node{ int num,c; }setree[maxn<<2]; struct{ int y,next; }ee[maxn<<1]; struct op{ int l,r; }mes[maxn]; int t,link[maxn],cnt; void insert(int a,int b) { ee[++t].y=b; ee[t].next=link[a]; link[a]=t; } void dfs(int root,int father) { int tmp=cnt; mes[root].l=cnt; for(int i=link[root];i;i=ee[i].next){ if(ee[i].y!=father){ dfs(ee[i].y,root); } } if(tmp==cnt){ mes[root].r=cnt++; return; } mes[root].r=cnt++; } void build(int l,int r,int rt) { setree[rt].num=0; setree[rt].c=0; if(l==r) return; int m=(l+r)>>1; build(lson); build(rson); } void pushdown(int rt,int len) { if(setree[rt].c){ setree[rt<<1].c=1-setree[rt<<1].c; setree[rt<<1].num=len-len/2-setree[rt<<1].num; setree[rt<<1|1].c=1-setree[rt<<1|1].c; setree[rt<<1|1].num=len/2-setree[rt<<1|1].num; setree[rt].c=0; } } void pushup(int rt) { setree[rt].num=setree[rt<<1].num+setree[rt<<1|1].num; } void update(int l,int r,int rt,int L,int R) { if(L<=l&&r<=R){ setree[rt].c=1-setree[rt].c; setree[rt].num=r-l+1-setree[rt].num; return; } int m=(l+r)>>1; pushdown(rt,r-l+1); if(L<=m) update(lson,L,R); if(R>m) update(rson,L,R); pushup(rt); } int query(int l,int r,int rt,int L,int R) { if(L<=l&&r<=R) return setree[rt].num; int m=(l+r)>>1; pushdown(rt,r-l+1); int ans=0; if(L<=m) ans+=query(lson,L,R); if(R>m) ans+=query(rson,L,R); return ans; } int main() { int n,m; while(~scanf("%d%d",&n,&m)){ memset(link,0,sizeof(link)); t=0; for(int i=2;i<=n;i++){ int a; scanf("%d",&a); insert(a,i); insert(i,a); } cnt=1; dfs(1,1); build(1,n,1); while(m--){ char s[5]; int a; scanf("%s%d",s,&a); if(s[0]=='o') update(1,n,1,mes[a].l,mes[a].r); else printf("%d\n",query(1,n,1,mes[a].l,mes[a].r)); } printf("\n"); } return 0; }
AC Code
相关文章推荐
- ZOJ 3686 : A Simple Tree Problem
- ZOJ_3686_A Simple Tree Problem(线段树成端更新)
- zoj 3686 A Simple Tree Problem
- zoj3686 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 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
- ZOJ3686 A Simple Tree Problem
- ZOJ 3686 A Simple Tree Problem
- zoj 3686 A Simple Tree Problem(dfs+线段树)
- ZOJ 3686 A Simple Tree Problem(线段树)
- ZOJ 3686 A Simple Tree Problem(将对树的操作转化成区间=>线段树)
- ZOJ 3686 A Simple Tree Problem (线段树)
- ZOJ 3686 A Simple Tree Problem(树转线段树+线段树区间更新)