POJ 3321 Apple Tree
2016-05-29 17:03:51
题目链接: POJ 3321 Apple Tree
题目大意:
给一棵树,一开始每一个节点权值都为1
两种操作:
1.C X 将X节点的权值取反
2.Q X 求以X为树根的子树的权值和
解法:
用树状数组维护DFS序
需要注意的:
1.需要一个数组存储每个节点的权值情况,便于修改
1 //Apple Tree (POJ No.3321) 2 //树状数组 3 #include<stdio.h> 4 #include<algorithm> 5 #include<string.h> 6 using namespace std; 7 const int maxn=100010; 8 struct edge 9 { 10 int to; 11 int next; 12 edge(){} 13 edge(int to,int next):to(to),next(next){} 14 }; 15 edge n[maxn*2]; 16 int head[maxn]; 17 int cnt; 18 char now[5]; 19 bool p[maxn]; 20 void insert(int x,int y) 21 { 22 n[++cnt]=edge(y,head[x]); 23 head[x]=cnt; 24 n[++cnt]=edge(x,head[y]); 25 head[y]=cnt; 26 return ; 27 } 28 int N,M; 29 int DFN[maxn]; 30 int son[maxn]; 31 int bit[maxn]; 32 int lowbit(int x) 33 { 34 return x&-x; 35 } 36 void add(int loc,int val) 37 { 38 for(int i=loc;i<=N;i+=lowbit(i))bit[i]+=val; 39 return ; 40 } 41 int query(int loc) 42 { 43 int sum=0; 44 for(int i=loc;i;i-=lowbit(i))sum+=bit[i]; 45 return sum; 46 } 47 int Index; 48 void DFS(int x) 49 { 50 DFN[x]=++Index; 51 son[x]=x; 52 for(int i=head[x];i;i=n[i].next) 53 { 54 if(DFN[n[i].to]==0) 55 { 56 DFS(n[i].to); 57 son[x]=son[n[i].to]; 58 } 59 } 60 return ; 61 } 62 int main() 63 { 64 scanf("%d",&N); 65 for(int i=1;i<N;i++) 66 { 67 int x,y; 68 scanf("%d %d",&x,&y); 69 insert(x,y); 70 add(i,1); 71 } 72 add(N,1); 73 DFS(1); 74 scanf("%d",&M); 75 for(int i=1;i<=M;i++) 76 { 77 int x; 78 scanf("%s %d",now,&x); 79 if(now[0]=='Q') 80 { 81 printf("%d\n",query(DFN[son[x]])-query(DFN[x]-1)); 82 } 83 else 84 { 85 p[x]^=1; 86 if(p[x]==1) 87 { 88 add(DFN[x],-1); 89 } 90 else add(DFN[x],1); 91 } 92 } 93 return 0; 94 }