Counting Offspring

Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2759    Accepted Submission(s): 956

Problem Description
You
are given a tree, it’s root is p, and the node is numbered from 1 to n.
Now define f(i) as the number of nodes whose number is less than i in
all the succeeding nodes of node i. Now we need to calculate f(i) for
any possible i.
 
Input
Multiple cases (no more than 10), for each case:
The first line contains two integers n (0<n<=10^5) and p, representing this tree has n nodes, its root is p.
Following n-1 lines, each line has two integers, representing an edge in this tree.
The input terminates with two zeros.
 
Output
For each test case, output n integer in one line representing f(1), f(2) … f(n), separated by a space.
 
Sample Input
15 7
7 10
7 1
7 9
7 3
7 4
10 14
14 2
14 13
9 11
9 6
6 5
6 8
3 15
3 12
0 0
思路:dfs序+线段树;
首先dfs序线性化,然后我们知道,如果某点是另个点的孩子节点,那么他必然在被另一个点的父亲节点所包括,所以从小到大查询[l[i],r[i]]区间的和,往线段树加点单点更新。复杂度n*log(n);
 1 #include<stdio.h>
2 #include<algorithm>
3 #include<queue>
4 #include<stdlib.h>
5 #include<iostream>
6 #include<string.h>
7 #include<set>
8 #include<map>
9 #include<vector>
10 using namespace std;
11 typedef long long LL;
12 typedef vector<int>Ve;
13 vector<Ve>vec(100005);
14 bool flag[100005];
15 int l[100005];
16 int r[100005];
17 int id[100005];
18 int cn = 0;
19 void dfs(int n);
20
21 int tree[100005*4];
22 void up(int l,int r,int k,int nn,int mm);
23 int ask(int l,int r,int k,int nn,int mm);
24 int main(void)
25 {
26 int n,p;
27 while(scanf("%d %d",&n,&p),n!=0&&p!=0)
28 { cn = 0;
29 for(int i = 0;i < 100005;i++)
30 vec[i].clear();
31 memset(flag,0,sizeof(flag));
32 for(int i = 0;i < n-1;i++)
33 {
34 int x,y;
35 scanf("%d %d",&x,&y);
36 vec[x].push_back(y);
37 vec[y].push_back(x);
38 }
39 dfs(p);
40 memset(tree,0,sizeof(tree));
41 for(int i = 1;i <= n;i++)
42 {
43 if(i == 1)
44 printf("%d",ask(l[i],r[i],0,1,cn));
45 else printf(" %d",ask(l[i],r[i],0,1,cn));
46 up(l[i],l[i],0,1,cn);
47 }
48 printf("\n");
49 }
50 return 0;
51 }
52 void dfs(int n)
53 {
54 flag[n] = true;
55 l[n] = ++cn;
56 for(int i = 0;i < vec[n].size();i++)
57 {
58 int d = vec[n][i];
59 if(!flag[d])
60 dfs(d);
61 }r[n] = cn;
62 }
63 void up(int l,int r,int k,int nn,int mm)
64 {
65 if(l > mm||r < nn)
66 {
67 return ;
68 }
69 else if(l <= nn&&r >= mm)
70 {
71 tree[k]++;return ;
72 }
73 up(l,r,2*k+1,nn,(nn+mm)/2);
74 up(l,r,2*k+2,(nn+mm)/2+1,mm);
75 tree[k] = tree[2*k+1]+tree[2*k+2];
76 }
77 int ask(int l,int r,int k,int nn,int mm)
78 {
79 if(l > mm||r < nn)
80 {
81 return 0;
82 }
83 else if(l <= nn&&r >= mm)
84 {
85 return tree[k];
86 }
87 else
88 {
89 int nx = ask(l,r,2*k+1,nn,(nn+mm)/2);
90 int ny = ask(l,r,2*k+2,(nn+mm)/2+1,mm);
91 return nx + ny;
92 }
93 }
 
Sample Output
0 0 0 0 0 1 6 0 3 1 0 0 0 2 0
 

Counting Offspring(hdu3887)的更多相关文章

  1. hdu3887 Counting Offspring

    Counting Offspring HDU - 3887 问你对于每个节点,它的子树上标号比它小的点有多少个 /* 子树的问题,dfs序可以很轻松的解决,因为点在它的子树上,所以在线段树中,必定在它 ...

  2. HDU3887 Counting Offspring [2017年6月计划 树上问题03]

    Counting Offspring Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  3. hdu 3887 Counting Offspring dfs序+树状数组

    Counting Offspring Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  4. HDU 3887 Counting Offspring(DFS序+树状数组)

    Counting Offspring Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  5. POJ 3321:Apple Tree + HDU 3887:Counting Offspring(DFS序+树状数组)

    http://poj.org/problem?id=3321 http://acm.hdu.edu.cn/showproblem.php?pid=3887 POJ 3321: 题意:给出一棵根节点为1 ...

  6. HDU 3887:Counting Offspring(DFS序+树状数组)

    http://acm.hdu.edu.cn/showproblem.php?pid=3887 题意:给出一个有根树,问对于每一个节点它的子树中有多少个节点的值是小于它的. 思路:这题和那道苹果树是一样 ...

  7. 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 ...

  8. 杭电 3887 Counting Offspring

    根据上篇翻译的文章以及很多个帖子,都讲述了树状数组最基本的功能就是tree[i]保存的是位置i左边小于等于a[i]的数的个数. 这样也就可以解释代码中为什么有f[i]=getsum(sd[i-1])- ...

  9. HDU 3887 Counting Offspring (树状数组+人工模拟栈)

    对这棵树DFS遍历一遍,同一节点入栈和出栈之间访问的节点就是这个节点的子树. 因此节点入栈时求一次 小于 i 的节点个数 和,出栈时求一次 小于 i 的节点个数 和,两次之差就是答案. PS.这题直接 ...

随机推荐

  1. 学习java 6.30

    学习内容:Java的运算符与C中类似,虽是类似,还是有点区别,在这里详细说明一下,即字符以及字符串的+操作,字符的+操作执行后需要赋值给表达式中数据范围最大的类型, 字符串的+操作,当+中有字符串,则 ...

  2. Rust 总章

    1.1 Rust安装 3.5 Rust Generic Types, Traits, and Lifetimes 3.6 String 与 切片&str的区别 https://openslr. ...

  3. Linux学习 - 挂载命令

    一.mount 1 功能 将外设手工挂载到目标挂载点 2 语法 mount  [-t 文件系统]  [设备文件名]  [挂载点] 3 范例 mkdir  /mnt/cdrom 在/mnt下创建一个cd ...

  4. Linux 网卡配置文件,命令详细设置

    1.配置文件/etc/hosts(本地主机ip地址映射,可以有多个别名)./etc/services(端口号与标准服务之间的对应关系)./etc/sysconfig/network(设置主机名,网关, ...

  5. spring的核心容器ApplicationContext

    //bean.xml配置文件 <?xml version="1.0" encoding="UTF-8"?><beans xmlns=" ...

  6. jstl中的choose标签

    <%@ page contentType="text/html;charset=UTF-8" language="java" %><%@ ta ...

  7. [BUUCTF]REVERSE——不一样的flag

    不一样的flag 附件 步骤 例行查壳儿,32位程序,无壳儿 32位ida载入,shift+f12检索程序里的字符串,看到了如图标记的字符串,加上下面又上下左右的选项,估计是道迷宫类型的题目 将迷宫字 ...

  8. 【python】青果教务系统模拟登陆

    使用 python 的 selenium + chrome 来模拟登陆学校教务系统 完整代码传至 github,增加了一个自动识别验证码的功能,不过是用的别人的轮子,识别度也不高 这是需要手动输入验证 ...

  9. 设置项目的日程排定方式(Project)

    <Project2016 企业项目管理实践>张会斌 董方好 编著 [项目]>[属性]>[项目信息]>[日程排定方法]>选取: 默认项是[项目开始日期]. 这两位是干 ...

  10. 联盛德 HLK-W806 (十一): 软件SPI和硬件SPI驱动ST7567液晶LCD

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...