HDU 3887 Counting Offspring

Counting Offspring



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
 
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#define pb push_back
using namespace std;
const int N=1e5+5;
int n,rt,dfs_clock,L[N],R[N],sum[N],ans[N];
vector<int>G[N];
inline void init()
{
    memset(sum,0,sizeof(sum));
    for(int i=1;i<=n;i++)G[i].clear();
    dfs_clock=0;
}
void dfs(int u,int fa)
{
    L[u]=++dfs_clock;
    for(int len=G[u].size(),i=0;i<len;i++)
    {
        int v=G[u][i];
        if(v==fa)continue;
        dfs(v,u);
    }
    R[u]=dfs_clock;
}
inline void add(int pos)
{
    for(int i=pos;i<=n;i+=i&(-i))
        sum[i]+=1;
}
inline int query(int pos)
{
    int res=0;
    for(int i=pos;i>0;i-=i&(-i))
        res+=sum[i];
    return res;
}
int main()
{
    while(scanf("%d%d",&n,&rt),n|rt)
    {
        init();
        for(int _=0;_<n-1;_++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            G[u].pb(v),G[v].pb(u);
        }
        dfs(rt,-1);
        for(int i=1;i<=n;i++)
        {
            ans[i]=query(R[i])-query(L[i]-1);
            add(L[i]);
        }
        for(int i=1;i<=n;i++)
            printf(i==n?"%d
":"%d ",ans[i]);
    }
    return 0;
}
 
原文地址:https://www.cnblogs.com/homura/p/5817637.html