您的位置:首页 > 移动开发

POJ 3321 Apple Tree(树状数组)

2012-10-13 17:03 351 查看
题目链接

很不错的一个题,开始搞了一个裸树的,后来听宝哥说用DFS把一个节点给离散成一段区间,重新标号,想了一下,好久没敲树状数组了,敲完发现还是TLE,比较发现我用左儿子,右兄弟的建树好像效率很低啊,改成链表形式的邻接表存图,终于过了。

#include <cstdio>
#include <cstring>
using namespace std;
int p[200001],str[200001],end[200001],n,num;
struct node//挂链的邻接表
{
int data;
struct node *next;
}*tree[200001],*temp;
int lowbit(int t)
{
return t&(-t);
}
void instert(int t,int d)
{
while(t <= n)
{
p[t] += d;
t += lowbit(t);
}
}
int getsum(int t)
{
int sum = 0;
while(t > 0)
{
sum += p[t];
t -= lowbit(t);
}
return sum;
}
void build(int father,int son)//建树
{
temp = new node;
temp -> data = son;
temp -> next = NULL;
temp -> next = tree[father];
tree[father] = temp;
}
void dfs(int x)
{
if(x == 0) return;
str[x] = num ++;
node *t;
t = tree[x];
while(t)
{
dfs(t->data);
t = t -> next;
}
end[x] = num-1;
}
int main()
{
int i,m,fa,son,key;
char ch;
while(scanf("%d",&n)!=EOF)
{
memset(p,0,sizeof(p));
for(i = 1; i <= n-1; i ++)
{
scanf("%d%d",&fa,&son);
build(fa,son);
}
num = 1;
dfs(1);
for(i = 1; i <= n; i ++)
{
instert(i,1);//初始化
}
scanf("%d%*c",&m);
for(i = 1; i <= m; i ++)
{
scanf("%c%d%*c",&ch,&key);
if(ch == 'Q')
printf("%d\n",getsum(end[key])-getsum(str[key]-1));
else
{
if(getsum(str[key]) - getsum(str[key]-1) == 1)//其实这里理解错题意了,就是简单的单点更新。。。
instert(str[key],-1);
else
instert(str[key],1);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: