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.
 

 

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

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

DFS序+树状数组HDU 3887 Counting Offspring

「 HDOJ P3887 」 Counting Offspring