POJ 3321 Apple Tree (树状数组)

题意:有n个苹果被树枝连接,这是一棵树!有两种操作C ind 和 Q ind,前者是摘下ind苹果,如果没有,哪么会长出新的一个,后者是查询ind有几个子苹果。

思路:第二道树状数组,自己想了很久不知道怎么转化,原来是利用树的性质,dfs一遍,记录每个节点的low和high值,那么他的子结点的low值和high值肯定在[low,high]之间,然后就可以通过tre[high[i]]-tre[low[i]-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\n",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;
}

原文地址:https://www.cnblogs.com/lvpengms/p/1718167.html