Counting Offspring(hdu3887)
Posted SJY
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Counting Offspring(hdu3887)相关的知识,希望对你有一定的参考价值。
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 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)的主要内容,如果未能解决你的问题,请参考以下文章
HDU 3887 Counting Offspring(DFS序)
hdu 3887 Counting Offspring dfs序+树状数组
HDU3887 Counting Offspring [2017年6月计划 树上问题03]