Counting Offspring(hdu3887)
来源:互联网 发布:算法导论 pdf 99 编辑:程序博客网 时间:2024/06/01 09:58
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.
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 else88 {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
0 0
- hdu3887 Counting Offspring
- Counting Offspring(hdu3887)
- Counting Offspring(hdu3887)
- Counting Offspring(hdu3887)
- Counting Offspring(hdu3887)
- Counting Offspring(hdu3887)
- HDU3887 Counting Offspring
- 线段树 HDU3887 Counting Offspring
- HDU3887 Counting Offspring【dfs序】
- HDU3887 - Counting Offspring(树状数组+模拟栈)
- hdu3887 Counting Offspring(dfs序+树状数组)
- hdu3887-dfs序&树状数组-Counting Offspring
- hdu3887 Counting Offspring(dfs序+树状数组)
- hdu 3887 Counting Offspring
- HDU 3887 Counting Offspring
- hdu 3887 Counting Offspring
- 杭电 3887 Counting Offspring
- HDU 3887 Counting Offspring 树状数组
- I2C的时序
- 基于ui-bootstrap写的Craousel——轮播
- 日期的获取和日期的转化
- ubuntu虽然安装了xchm,KchmViewer也打不开html,css的帮助文档
- 自定义简单视频播放器
- Counting Offspring(hdu3887)
- 后台 转化出现乱码的代码
- pacific vis 2017 评审流程
- ios 闪退,以及崩溃日志查看
- IDEA中ivy的使用
- 产生随机数,IO流写入文件
- 关于Retrofit使用HTTPS的相关问题
- 机器学习-3 cost function 代价函数
- Windows编程入门的常见问题