思路:
对结点重编号,使得每棵子树内的结点的编号连续,便可将问题转化为树状数组求区间和,
用后序遍历对整棵树进行重编号能满足要求。
除了要在每个结点处记录新编号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 ;
}