HDU 3887 Counting Offspring(DFS序)

Counting Offspring

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

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

Sample Output

0 0 0 0 0 1 6 0 3 1 0 0 0 2 0

Author

bnugong

Source

2011 Multi-University Training Contest 5 - Host by BNU

题意:求在一个有根节点的树中 每个节点的子树中有多少个小于改点的序号

DFS序找到每个节点的时间戳  用树状数组直接维护这个区间就可以了

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cctype>
 5 #include<cmath>
 6 #include<cstring>
 7 #include<map>
 8 #include<set>
 9 #include<queue>
10 #include<vector>
11 #include<algorithm>
12 #include<string>
13 #define ll long long
14 #define eps 1e-10
15 #define LL unsigned long long
16 using namespace std;
17 const int inf=0x3f3f3f3f;
18 const int N=200000+10;
19 const int mod=1e9+7;
20 int head[N];
21 int tot,time;
22 int L[N],R[N];
23 struct node{
24     int to,next;
25 }edge[N<<1];
26 int a[N*5];
27 void init(){
28     memset(head,-1,sizeof(head));
29     tot=0;
30     time=0;
31 }
32 void add(int u,int v){
33     edge[tot].to=v;
34     edge[tot].next=head[u];
35     head[u]=tot++;
36 }
37 void DFS(int x,int fa){
38     L[x]=++time;
39     for(int i=head[x];i!=-1;i=edge[i].next){
40         int v=edge[i].to;
41         if(v==fa)continue;
42         DFS(v,x);
43     }
44     R[x]=time;
45
46 }
47 int lowbit(int x){
48     return x&(-x);
49 }
50 void update(int x,int y){
51     while(x<=time){
52         a[x]=a[x]+y;
53         x=x+lowbit(x);
54     }
55 }
56 int getsum(int x){
57     int ans=0;
58     while(x>0){
59         //cout<<2<<endl;
60         ans=ans+a[x];
61         x=x-lowbit(x);
62     }
63     return ans;
64 }
65 int main(){
66     int n,p;
67     while(scanf("%d%d",&n,&p)!=EOF){
68         if(n==0&&p==0)break;
69         init();
70         memset(a,0,sizeof(a));
71         for(int i=1;i<n;i++){
72             int u,v;
73             scanf("%d%d",&u,&v);
74             add(u,v);
75             add(v,u);
76         }
77         DFS(p,-1);
78         for(int i=1;i<=n;i++){
79             int ans=getsum(R[i])-getsum(L[i]-1);
80             if(i!=n)cout<<ans<<" ";
81             else{
82                 cout<<ans<<endl;
83             }
84             update(L[i],1);
85         }
86     }
87 }
时间: 2024-08-10 08:07:45

HDU 3887 Counting Offspring(DFS序)的相关文章

hdu 3887 Counting Offspring dfs序+树状数组

Counting Offspring Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) 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 numbe

HDU 3887 Counting Offspring(DFS序求子树权值和)

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

hdu 3887 Counting Offspring(DFS序【非递归】+树状数组)

题意: N个点形成一棵树.给出根结点P还有树结构的信息. 输出每个点的F[i].F[i]:以i为根的所有子结点中编号比i小的数的个数. 0<n<=10^5 思路: 方法一:直接DFS,进入结点x时记录一下比x小的数的个数.出来x时记录一下比x小的数的个数.相减就是F[x].结合树状数组. 方法二:写下DFS序.对DFS序列建线段树.然后从小到大对结点进行插入.用线段树统计. 代码:(方法一) int const N=1e5+5; int n,p; vector<int> G[N];

【DFS序+树状数组】HDU 3887 Counting Offspring

http://acm.hdu.edu.cn/showproblem.php?pid=3887 [题意] 给定一棵树,给定这棵树的根 对于每个结点,统计子树中编号比他小的结点个数 编号从小到大一次输出 [思路] 从小到大处理每个结点,即统计当前结点的结果后,把当前结点插入到树状数组中 [AC] 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 5 const int maxn=1e5+2; 6 c

hdu 3887 Counting Offspring

题目大意:给你一棵树,求每个父节点的子树中序号小于父节点序号的节点个数. #include <set> #include <map> #include <queue> #include <stack> #include <math.h> #include <time.h> #include <vector> #include <string> #include <stdio.h> #include

hdu 5877 Weak Pair dfs序+树状数组+离散化

Weak Pair Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Problem Description You are given a rooted tree of N nodes, labeled from 1 to N. To the ith node a non-negative value ai is assigned.An ordered pair of no

HDU 2952 Counting Sheep (DFS找联通块)

题目链接:请戳这里.   题目大意及思路:读懂题意就好了,就是DFS找联通块. 没什么好说的,见代码吧. #include<cstdio> #include<cstring> #include<algorithm> #define N 100+5 using namespace std; int n,m; char g[N][N]; int dir[4][2]={1,0,0,1,-1,0,0,-1}; void dfs(int x,int y) { for(int i=

HDU 5692 线段树+dfs序

Snacks Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1779    Accepted Submission(s): 427 Problem Description 百度科技园内有n 个零食机,零食机之间通过n−1 条路相互连通.每个零食机都有一个值v ,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充,零食机的价值v

HDU - 5952 Counting Cliques(DFS)

A clique is a complete graph, in which there is an edge between every pair of the vertices. Given a graph with N vertices and M edges, your task is to count the number of cliques with a specific size S in the graph. InputThe first line is the number