poj 3321 Apple Tree
2931 ワード
http://poj.org/problem?id=3321
テーマ:
N個の点からなる木に各点を1に初期化するには2つの操作があります
Cx:変化点の値は1から0へ0へ1へ
Q x:xをルートとするサブツリー上のポイント値の和を聞く
考え方:
主に木を木の配列にマッピングします
一度dfsは点再番号lowとhigh lowをこの点を検索したばかりの時のカウントを表し、highはそのサブツリー内のすべてのノードを検索して戻ってきたカウント番号である
例えばまたn個の点ほどルートノード1のlow=1,high=2*n
これで木の配列にマッピングされます.
コードとそのコメント:
テーマ:
N個の点からなる木に各点を1に初期化するには2つの操作があります
Cx:変化点の値は1から0へ0へ1へ
Q x:xをルートとするサブツリー上のポイント値の和を聞く
考え方:
主に木を木の配列にマッピングします
一度dfsは点再番号lowとhigh lowをこの点を検索したばかりの時のカウントを表し、highはそのサブツリー内のすべてのノードを検索して戻ってきたカウント番号である
例えばまたn個の点ほどルートノード1のlow=1,high=2*n
これで木の配列にマッピングされます.
コードとそのコメント:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<algorithm>
#include<stack>
using namespace std;
const int N=100010;
struct node
{
struct tt *next;
}mem[N];
struct tt
{
struct tt *next;
int j;
};
int n,I;//n is the number of apples I
int c[N*2];
int high[N];
int low[N];
bool visited[N];
int apple[N];//
void build(int i,int j)//
{
struct tt *t=new tt;
t->j=j;
t->next=mem[i].next;
mem[i].next=t;
}
void dele()//
{
for(int i=1;i<=n;++i)
mem[i].next=NULL;
}
int lowbit(int x)
{
return x&(-x);
}
void Add(int x,int k)
{
for(int i=x;i<=2*n;i+=lowbit(i))
{
c[i]+=k;
}
}
int Sum(int x)
{
int sum=0;
for(int i=x;i>0;i-=lowbit(i))
{
sum+=c[i];
}
return sum;
}
void dfs(int x)//
{
visited[x]=true;
++I;
low[x]=I;
struct tt *t=new tt;
t=mem[x].next;
while(t!=NULL)
{
if(visited[t->j]==false)
{
dfs(t->j);
}
t=t->next;
}
++I;
high[x]=I;
}
int main()
{
int m;
while(scanf("%d",&n)!=EOF)
{
memset(c,0,sizeof(c));
for(int i=1;i<n;++i)
{
int l,r;
scanf("%d %d",&l,&r);
build(l,r);
build(r,l);
}
I=0;
memset(visited,false,sizeof(visited));
dfs(1);
for(int i=1;i<=n;++i)
{
apple[i]=1;
}
for(int i=1;i<=2*n;++i)
{
Add(i,1);//
}
scanf("%d",&m);
while(m--)
{
char c;
int k;
getchar();
scanf("%c %d",&c,&k);
if(c=='Q')
{
printf("%d
",(Sum(high[k])-Sum(low[k]-1))/2);
}else
{
if(apple[k]==1)
{
apple[k]=0;
Add(low[k],-1);
Add(high[k],-1);
}
else
{
apple[k]=1;
Add(low[k],1);
Add(high[k],1);
}
}
}
dele();
}
return 0;
}