poj上面的一道求子树上苹果的题目,网上看了很多题解,下面我来回忆一下,基本来源于大神的微博,http://blog.csdn.net/zhang20072844,我来做个搬运工。
先将树的n条边上节点重新标号,让每一棵子树上的节点编号构成一个连续的区间,然后利用dfs将第i个节点表示的区间下限,上限存进数组low[u],high[u]。树状数组c[i]=a[i-2^k+1]+a[i-2^k+2]+.....a[i],也就是i-2^k+1到i之间的苹果总数,每一个a[i]表示树上一个分叉,i是经过重新标号后的表示节点的值。可以通过add(low[i],1)为第i(原苹果树中标号)个节点增加一个苹果,同时更新树状数组中和i(也就是元素a[low[i]]有关的c[j]值,这样查询low[i]到high[i]区间范围内的苹果数目便可以通过sum(high[i])-sum(low[i]-1),其中sum(t)表示a[i]+a[2].....a[t]之和也就是这些节点上苹果数目。

 #include<stdio.h>
#include<string.h>
#define N 100010 typedef struct
{
int to,next;
} Edge;
Edge edge[N];
int low[N],high[N],vis[N],c[N*],head[N],pick[N];
int dep,p,n; void addedge(int cu,int cv)
{
edge[p].to=cv;
edge[p].next=head[cu];
head[cu]=p++;
} void dfs(int u)
{
low[u]=++dep;
vis[u]=;
int i;
for(i=head[u]; i!=-; i=edge[i].next)
{
if(!vis[edge[i].to])
dfs(edge[i].to);
}
high[u]=dep;
} int lowbit(int x)
{
return x&(-x);
}
void add(int t,int v)
{
while(t<=n)
{
c[t]+=v;
t+=lowbit(t);
}
} int sum(int t)
{
int res=;
while(t>)
{
res+=c[t];
t-=lowbit(t);
}
return res;
} int main(void)
{
int m,i,u,v;
memset(head,-,sizeof(head));
scanf("%d",&n);
for(i=; i<n; i++)
{
scanf("%d%d",&u,&v);
addedge(u,v);
}
dfs();
for(i=; i<=n; i++)
{
add(i,);
pick[i]=;
}
scanf("%d",&m);
while(m--)
{
getchar();
char op;
scanf("%c%d",&op,&i);
if(op=='Q')
printf("%d\n",sum(high[i])-sum(low[i]-));
else
{
if(pick[i])
{
add(low[i],-);
pick[i]=;
}
else
{
add(low[i],);
pick[i]=;
}
}
}
return ;
}

POJ_3321_APPLE_TREE的更多相关文章

随机推荐

  1. JUnit4注解基本介绍

    @After If you allocate external resources in a Before method you need to release them after the test ...

  2. Fragment碎片频繁来回切换的时候报java.lang.IllegalStateException: No activity

    出现这个问题的原因是因为使用的transcation.replace(fragmentTwo);的方式进行碎片切换的. 解决方案是使用add和show.hide方法组合实现碎片的切换(应该是显示.隐藏 ...

  3. 玩转html5<canvas>画图

    导航 前言 基本知识 绘制矩形 清除矩形区域 圆弧 路径 绘制线段 绘制贝塞尔曲线 线性渐变 径向渐变(发散) 图形变形(平移.旋转.缩放) 矩阵变换(图形变形的机制) 图形组合 给图形绘制阴影 绘制 ...

  4. WebUploader——一个页面多个实例上传图片

    WebUploader官方例子看的不是很清楚,自己也是费了点劲自己写了一下. 需求:一个单页需要多个实例来上传,一次可上传多张 条件:后台接收C# 首先:引入webuploader     webup ...

  5. 20151216JqueryUI学习笔记---按钮

    按钮(button) , 可以给生硬的原生按钮或者文本提供更多丰富多彩的外观. 它不单单可以设置按钮或文本,还可以设置单选按钮和多选按钮.一. 使用 button 按钮使用 button 按钮 UI ...

  6. Linq语法

    希望能帮助一些linq新手. 开门见山 读这篇文章之前,我先说下,每一种搜索结果集,我都以三种方式变现出来,为啦更好的理解,希望不要嫌我啰嗦. 1.简单的linq语法 //1 var ss = fro ...

  7. Timestamp的作用及与字符串的相互转换 .

    一.Timestamp的介绍 每一个数据库都有一个计数器,这个计数器记录着数据行的插入.更新行为.如果我们为一个表中增加 timestamp 列,那么,该列将记录每一个数据行的计数器值.假如数据库中当 ...

  8. C#数据类型转换的几种形式

    1.隐式转换:一般是低类型向高类型转化,能够保证值不发生变化. 隐式数值C#数据类型转换: 从 sbyte 到 short.int.long.float.double 或 decimal. 从 byt ...

  9. 我也来学着写写WINDOWS服务-解析xml抓取数据并插入数据库

    项目告一段落,快到一年时间开发了两个系统,一个客户已经在试用,一个进入客户测试阶段,中间突然被项目经理(更喜欢叫他W工)分派一个每隔两小时用windows服务去抓取客户提供的外网xml,解析该xml, ...

  10. OC加强-day04

    #pragma mark 00知识回顾 //定义一个函数 函数没有返回值函数有一个参数:返回值是double 参数是两个int的block void test(int a); void test(do ...