pku3321 Apple Tree
思路:
对结点重编号,使得每棵子树内的结点的编号连续,便可将问题转化为树状数组求区间和,
用后序遍历对整棵树进行重编号能满足要求。
除了要在每个结点处记录新编号tag外,还要记录该结点对应的子树的最小结点编号mn,对
于每个结点x,其苹果个数为sum(x.tag)-sum(x.mn-1)。
#include <iostream>
#include <algorithm>
using namespace std;
#define MAXN 100001
int n,m,cnt,c[MAXN],a[MAXN];
//cnt在结点重编号中作统计用,a[i]表示重编号后第i号结点上的苹果数
bool s[MAXN];
struct Link{
int v;
Link *next;
}*link[MAXN];
struct Node{
int tag,mn;
}nod[MAXN];
void init(){
memset(link,NULL,sizeof(link));
memset(nod,0,sizeof(nod));
memset(c,0,sizeof(c));
memset(s,false,sizeof(s));
cnt=1;
Link *temp;
int i,x,y;
for(i=0;i<n-1;i++){
scanf("%d%d",&x,&y);
temp=new Link;
temp->v=x;
temp->next=link[y];
link[y]=temp;
temp=new Link;
temp->v=y;
temp->next=link[x];
link[x]=temp;
}
}
void dfs(int u){
Link *temp;
nod[u].mn=cnt;
temp=link[u];
while(temp){
if(!s[temp->v]){
s[temp->v]=true;
dfs(temp->v);
}
temp=temp->next;
}
nod[u].tag=cnt++;
}
inline int lowbit(int x){
return x&(-x);
}
void change(int x){
int i;
if(a[x])
for(i=x;i<cnt;i+=lowbit(i))
c[i]++;
else
for(i=x;i<cnt;i+=lowbit(i))
c[i]--;
}
int sum(int x){
int i,res=0;
for(i=x;i>0;i-=lowbit(i))
res+=c[i];
return res;
}
int main(){
int i,x;
char str[3];
while(scanf("%d",&n)!=EOF){
init();
s[1]=true;
dfs(1);
scanf("%d",&m);
for(i=1;i<cnt;i++){
a[i]=1;
change(i);
}
for(i=0;i<m;i++){
scanf("%s",str);
scanf("%d",&x);
if(str[0]=='Q')
printf("%d\n",sum(nod[x].tag)-sum(nod[x].mn-1));
else{
a[nod[x].tag]=(a[nod[x].tag]+1)%2;
change(nod[x].tag);
}
}
}
return 0;
}
#include <algorithm>
using namespace std;
#define MAXN 100001
int n,m,cnt,c[MAXN],a[MAXN];
//cnt在结点重编号中作统计用,a[i]表示重编号后第i号结点上的苹果数
bool s[MAXN];
struct Link{
int v;
Link *next;
}*link[MAXN];
struct Node{
int tag,mn;
}nod[MAXN];
void init(){
memset(link,NULL,sizeof(link));
memset(nod,0,sizeof(nod));
memset(c,0,sizeof(c));
memset(s,false,sizeof(s));
cnt=1;
Link *temp;
int i,x,y;
for(i=0;i<n-1;i++){
scanf("%d%d",&x,&y);
temp=new Link;
temp->v=x;
temp->next=link[y];
link[y]=temp;
temp=new Link;
temp->v=y;
temp->next=link[x];
link[x]=temp;
}
}
void dfs(int u){
Link *temp;
nod[u].mn=cnt;
temp=link[u];
while(temp){
if(!s[temp->v]){
s[temp->v]=true;
dfs(temp->v);
}
temp=temp->next;
}
nod[u].tag=cnt++;
}
inline int lowbit(int x){
return x&(-x);
}
void change(int x){
int i;
if(a[x])
for(i=x;i<cnt;i+=lowbit(i))
c[i]++;
else
for(i=x;i<cnt;i+=lowbit(i))
c[i]--;
}
int sum(int x){
int i,res=0;
for(i=x;i>0;i-=lowbit(i))
res+=c[i];
return res;
}
int main(){
int i,x;
char str[3];
while(scanf("%d",&n)!=EOF){
init();
s[1]=true;
dfs(1);
scanf("%d",&m);
for(i=1;i<cnt;i++){
a[i]=1;
change(i);
}
for(i=0;i<m;i++){
scanf("%s",str);
scanf("%d",&x);
if(str[0]=='Q')
printf("%d\n",sum(nod[x].tag)-sum(nod[x].mn-1));
else{
a[nod[x].tag]=(a[nod[x].tag]+1)%2;
change(nod[x].tag);
}
}
}
return 0;
}