POJ 3321 Apple Tree(ツリー配列)

19917 ワード

标题:n個のリンゴが枝でつながっていて、これは1本の木です!C indとQ indの2つの操作があり、前者はindアップルを外し、もしなければ、新しい1つが生み出され、後者はindにいくつかの子アップルがあるかを調べる.
構想:第2の木の形の配列、自分で長い間どのように転化することを考えていないで、もとは木の性質を利用して、dfsは一回、各ノードのlowとhigh値を記録して、それでは彼の子の結点のlow値とhigh値はきっと[low,high]の間で、それからtre[high[i]-tre[low[i]-1]を通じて現在のノードの子の結点の個数を調べることができて、汗は1つ、自分のものじゃないし...

  
    
/* Apple tree
* , , ,low[],high[]
* , O(log(n))
*/
#include
< iostream >
#include
< cstdio >
#include
< algorithm >
#include
< memory.h >
#include
< cmath >
#include
< bitset >
#include
< queue >
#include
< vector >
using namespace std;

const int BORDER = ( 1 << 20 ) - 1 ;
const int MAXSIZE = 37 ;
const int MAXN = 202000 ;
const int INF = 1000000000 ;
#define CLR(x,y) memset(x,y,sizeof(x))
#define ADD(x) x=((x+1)&BORDER)
#define IN(x) scanf("%d",&x)
#define OUT(x) printf("%d
",x)

#define MIN(m,v) (m)<(v)?(m):(v)
#define MAX(m,v) (m)>(v)?(m):(v)
#define ABS(x) ((x)>0?(x):-(x))

typedef
struct {
int v,next;
}Edge;

Edge edge[MAXN
* 20 ];
int tre[MAXN],low[MAXN],net[MAXN],high[MAXN];
int n_tre,n,cnt,index,m;
bool visit[MAXN];

void add_edge( const int & u, const int & v)
{
edge[index].v
= v;
edge[index].next
= net[u];
net[u]
= index;
++ index;
edge[index].v
= u;
edge[index].next
= net[v];
net[v]
= index;
++ index;
}
int init()
{
cnt
= 0 ;
index
= 0 ;
CLR(tre,
0 );
CLR(visit,
0 );
CLR(net,
- 1 );
return 0 ;
}
int lowbit( int x)
{
return x & ( - x);
}
void modify( int ind, int delta)
{
while ( ind <= n_tre)
{
tre[ind]
+= delta;
ind
+= lowbit(ind);
}
}
int get_sum( int ind)
{
int sum = 0 ;
while (ind > 0 )
{
sum
+= tre[ind];
ind
-= lowbit(ind);
}
return sum;
}
int input()
{
int i,a,b;
for (i = 1 ; i < n; ++ i)
{
scanf(
" %d %d " , & a, & b);
add_edge(a,b);
}
return 0 ;
}
void dfs( const int & u)
{
++ cnt;
visit[u]
= true ;
low[u]
= cnt;
for ( int i = net[u]; i != - 1 ; i = edge[i].next)
if ( ! visit[edge[i].v])
dfs(edge[i].v);
high[u]
= cnt;
}
int work()
{
int i,j,tmp,ind;
int ans;
char c[ 10 ];
n_tre
= n << 1 ;
dfs(
1 );
IN(m);
CLR(visit,
0 );
for (i = 0 ; i < m; ++ i)
{
scanf(
" %s " ,c);
scanf(
" %d " , & ind);
if (c[ 0 ] == ' Q ' )
{
ans
= high[ind] - low[ind] + 1 +
get_sum(high[ind])
- get_sum(low[ind] - 1 );
OUT(ans);
}
else
{
if (visit[ind])
modify(low[ind],
1 );
else
modify(low[ind],
- 1 );
visit[ind]
^= 1 ;
}
}
return 0 ;
}
int main()
{
IN(n);
{
init();
input();
work();
}
return 0 ;
}