HDU-3887-Counting Offspring (dfs + Fenwick tree)

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

Problem-solving ideas:

Meaning of the questions: Given a tree, ask each child node of the tree, there are several smaller number than his.
Requires a number smaller than his first thought was Fenwick tree, can solve this problem, then one is how to solve the problem child of the tree.
Read online a lot of problem solution are the same dfs mark, then a sum of about minus, in fact, can not have too much trouble ah.
Since it is only the sub-tree would affect the results, then entering a node when the first record value sum (x), and then after the completion of the sub-tree search, and then seek again the value of sum (x), and two minus it is the answer.
Finally, then x is also marked.

AC Code:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5+10;
vector<int> nodes[N];

int ans[N],vis[N];
int bit[N],n;

int lowbit(int x)
{
    return x&(-x);
}
void add(int i,int x)
{
    while(i<=n)
    {
        bit[i]+=x;
        i+=lowbit(i);
    }
}
void sub(int i,int x)
{
    while(i<=n)
    {
        bit[i]-=x;
        i+=lowbit(i);
    }
}
int sum(int i)
{
    int res=0;
    while(i>0)
    {
        res+=bit[i];
        i-=lowbit(i);
    }
    return res;
}

void dfs(int x)
{
    int sz = nodes[x].size();
    int pre = sum(x);
    vis[x] = 1;
    for(int i = 0 ; i < sz ; i ++)
        if(!vis[nodes[x][i]])
            dfs(nodes[x][i]);
    ans[x] = sum(x)-pre;
    add(x,1);
}

signed main()
{
    int m;
    while(~scanf("%lld%lld",&n,&m) &&  n+m )
    {
        for(int i = 0 ; i <= n ; i ++)
            nodes[i].clear();
        for(int i = 0 ; i < n-1 ; i ++)
        {
            int a,b;
            scanf("%lld%lld",&a,&b);
            nodes[a].push_back(b);
            nodes[b].push_back(a);
        }
        memset(bit,0,sizeof(bit));
        memset(vis,0,sizeof(vis));
        dfs(m);
        for(int i = 1 ; i < n ; i ++)
            printf("%lld ",ans[i]);
        printf("%lld\n",ans[n]);
    }
}

Published 104 original articles · won praise 7 · views 4078

Guess you like

Origin blog.csdn.net/qq_43461168/article/details/103428150