[hdu3887] Counting Offspring
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
Source
2011 Multi-University Training Contest 5 - Host by BNU
题意
给一棵\(n\)个节点的树和树的根节点\(p\),定义\(f(i)\)为以\(i\)为根节点的子树中,编号比\(i\)小的节点个数,求所有的\(f(i)\)
题解
先\(DFS\)求出\(DFS\)序,再从小到大统计以它为根节点的子树中比它小的节点个数,统计之后再往线段树加点单点更新,因为这样可以保证统计的每一个都比当前的数小
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<bitset>
#include<vector>
#include<iomanip>
#include<map>
#include<set>
using namespace std;
const int N=250000;
int n,p,t,t1[N],t2[N],c[N],v[N];
struct edge
{
int v,nx;
}e[N];
int ne,hd[N];
void Init()
{
ne=0,t=0;
for(int i=1;i<=n;++i)
hd[i]=-1,v[i]=0,c[i]=0;
}
void Build(int u,int v)
{
++ne,e[ne]=(edge){v,hd[u]},hd[u]=ne;
}
void Read()
{
int u,v;
for(int i=1;i<n;++i)
{
scanf("%d%d",&u,&v);
Build(u,v),Build(v,u);
}
}
void Dfs(int id)
{
if(v[id]) return;
v[id]=1,++t,t1[id]=t;
for(int i=hd[id];i!=-1;i=e[i].nx)
Dfs(e[i].v);
t2[id]=t;
}
int Lowbit(int x)
{
return x&-x;
}
int Get_sum(int id)
{
int Res=0;
for(;id;)
{
Res+=c[id],
id-=Lowbit(id);
}
return Res;
}
void Updata(int id,int num)
{
for(;id<=n;)
{
c[id]+=num,
id+=Lowbit(id);
}
}
void Get_Ans()
{
printf("%d",Get_sum(t2[1])-Get_sum(t1[1]-1));
Updata(t1[1],1);
for(int i=2;i<=n;++i)
{
printf(" %d",Get_sum(t2[i])-Get_sum(t1[i]-1));
Updata(t1[i],1);
}
putchar('\n');
}
int main()
{
for(scanf("%d%d",&n,&p);n|p;scanf("%d%d",&n,&p))
Init(),Read(),Dfs(p),Get_Ans();
return 0;
}
本文作者:OItby @ https://www.cnblogs.com/hihocoder/
未经允许,请勿转载。