杭电 3887 Counting Offspring
根据上篇翻译的文章以及很多个帖子,都讲述了树状数组最基本的功能就是tree[i]保存的是位置i左边小于等于a[i]的数的个数.
这样也就可以解释代码中为什么有f[i]=getsum(sd[i-1])-getsum(st[i]))/2。因为getsum保存的就是左边比i小的数,注意因为序列是通过dfs求出的,因而每个节点都有进入和退出过程,也就是每个节点都出现了2次,比如说对于数4来说,有4个节点,假设3为顶点,边的关系是3-2-1,3-2-4,那么dfs扫描出的序列就是3,2,1,1,4,4,2,3.所以求出的最终结果就需要除以2,因为每个数字都出现了2次。
至于为什么是从n-->1,我也纠结了半天,后来总算是YY出了一点思路【也可能不对】,因为已经将tree初始过了,考虑最原始的BIT,我们是一边遍历原始数组,一边getsum,一边update树,更新时,tree[i]+=1,这里提前将tree update过了,那么只能从后向前走,update(-1)了。假定最后一个点是n,那么在考虑其他节点的时候是不需要考虑这个点的,因为任何一个点都比最后这个点小,所以。。。update的时候是(-1)。
代码中注释的部分是原作者的,为了证实一下我自己YY出的结果是否正确,我测试了一下,果然A掉了。所以我的想法应该是对的,如果从头开始的话,需要从头遍历数组,得结果的时候需要两次update(1),这样的话仅仅需要从1-->就可以了。
代码如下:
#pragma comment(linker,"/STACK:100000000,100000000")
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std; const int maxn=100005;
vector<int>vt[maxn];
int bit[2*maxn];
int que[2*maxn];
int st[maxn];
int sd[maxn];
int f[maxn];
int n, rt, num; void dfs(int u, int fa)
{
que[++num]=u;
for(int i=0; i<vt[u].size(); i++)
{
int v=vt[u][i];
if(v==fa) continue;
dfs(v,u);
}
que[++num]=u;
} int lowbit(int x)
{
return x&(-x);
} void update(int x, int val)
{
while(x<=num)
{
bit[x]+=val;
x+=lowbit(x);
}
} int getsum(int x)
{
int ans=0;
while(x>0)
{
ans+=bit[x];
x-=lowbit(x);
}
return ans;
} int main()
{
//int a=4,b=3;
//printf("%d",a|b);
while(~scanf("%d%d",&n,&rt),n+rt)
{
for(int i=0; i<=n; i++)
vt[i].clear();
for(int i=1; i<n; i++)
{
int x, y;
scanf("%d%d",&x,&y);
vt[x].push_back(y);
vt[y].push_back(x);
}
fill(st+1,st+1+n,0);
num=0;
dfs(rt,-1);
//每个节点开始和结束的位置
for(int i=1; i<=num; i++)
{
if(!st[que[i]])
st[que[i]]=i;
else
sd[que[i]]=i;
}
memset(bit,0,sizeof(bit));
/*
for(int i=1; i<=num; i++)
update(i,1);
for(int i=n; i>=1; i--)
{
f[i]=(getsum(sd[i]-1)-getsum(st[i]))/2;
update(st[i],-1);
update(sd[i],-1);
}*/
for(int i=1;i<=n;i++)//这里是测试从1-->n的,注意对比
{
update(st[i],1);
update(sd[i],1);
f[i]=(getsum(sd[i]-1)-getsum(st[i]))/2;
}
printf("%d",f[1]);
for(int i=2; i<=n; i++)
printf(" %d",f[i]);
puts("");
}
return 0;
}
杭电 3887 Counting Offspring的更多相关文章
- hdu 3887 Counting Offspring dfs序+树状数组
Counting Offspring Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- HDU 3887 Counting Offspring(DFS序+树状数组)
Counting Offspring Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- Hdu 3887 Counting Offspring \ Poj 3321 Apple Tree \BZOJ 1103 [POI2007]大都市meg
这几个题练习DFS序的一些应用. 问题引入: 给定一颗n(n <= 10^5)个节点的有根树,每个节点标有权值,现有如下两种操作: 1.C x y 以节点x的权值修改为y. 2.Q x ...
- 【DFS序+树状数组】HDU 3887 Counting Offspring
http://acm.hdu.edu.cn/showproblem.php?pid=3887 [题意] 给定一棵树,给定这棵树的根 对于每个结点,统计子树中编号比他小的结点个数 编号从小到大一次输出 ...
- HDU 3887 Counting Offspring (树状数组+人工模拟栈)
对这棵树DFS遍历一遍,同一节点入栈和出栈之间访问的节点就是这个节点的子树. 因此节点入栈时求一次 小于 i 的节点个数 和,出栈时求一次 小于 i 的节点个数 和,两次之差就是答案. PS.这题直接 ...
- hdu 3887 Counting Offspring(DFS序【非递归】+树状数组)
题意: N个点形成一棵树.给出根结点P还有树结构的信息. 输出每个点的F[i].F[i]:以i为根的所有子结点中编号比i小的数的个数. 0<n<=10^5 思路: 方法一:直接DFS,进入 ...
- 杭电ACM分类
杭电ACM分类: 1001 整数求和 水题1002 C语言实验题——两个数比较 水题1003 1.2.3.4.5... 简单题1004 渊子赛马 排序+贪心的方法归并1005 Hero In Maze ...
- hdu3887 Counting Offspring
Counting Offspring HDU - 3887 问你对于每个节点,它的子树上标号比它小的点有多少个 /* 子树的问题,dfs序可以很轻松的解决,因为点在它的子树上,所以在线段树中,必定在它 ...
- acm入门 杭电1001题 有关溢出的考虑
最近在尝试做acm试题,刚刚是1001题就把我困住了,这是题目: Problem Description In this problem, your task is to calculate SUM( ...
随机推荐
- [Cycle.js] Hello World in Cycle.js
Now you should have a good idea what Cycle.run does, and what the DOM Driver is. In this lesson, we ...
- Timer.4 - Using a member function as a handler
In this tutorial we will see how to use a class member function as a callback handler. The program s ...
- hdu 2822 Dogs(优先队列)
题目链接:hdu2822 会优先队列话这题很容易AC.... #include<stdio.h> #include<string.h> #include<queue> ...
- js判断是否是数字通用写法
function isNumber(value){ var isNumber = value.match(/^(-?\d+)(\.\d+)?$/g) !=null; if(value.substrin ...
- jquery文本框验证字符长度和只能输入数字
<input type="text" class="chujia" onkeyup="this.value=this.value.replace ...
- web并发模型
并发:cpu划分时间片,轮流执行每个请求任务,时间片到期后,换到下一个. 并行:在多核服务器上,每个cpu内核执行一个任务,是真正的并行 IO密集型的应用,由于请求过程中很多时间都是外部IO操作,CP ...
- 在asp.net中导出表格Excel数据
第一步:需要引用org.in2bits.MyXls程序集到使用页面 第二步:前台代码 <asp:Button ID="LeadingOut" runat="serv ...
- weblogic开机启动脚本
1.在/home/bea/startBeaAll目录内创建一个startBeaAll.sh文件,加入如下内容(把相应目录与命令修改即可,红字部分为修改地方): #!/bin/sh echo " ...
- java.lang.NoClassDefFoundError: javax/xml/stream/XMLStreamException
?缺少jsr173_1.0_api.jar 包 或者jdk版本不对(包括工程和tomcat等服务器的jdk版本) 以前的一个xfire工程,今天重新导进后不能运行,修改工程的jdk版本不行,最后发现是 ...
- XML巩固
一.XML基础 1.XML区分大小写, 2.XML属性值必须有引号(单引双引均可) 3.XML必须有根元素 4.一些特殊字符的需要用实体引用来替换 < < 小于 > > 大于 ...