zoukankan      html  css  js  c++  java
  • [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('
    ');
    }
    
    int main()
    {
    	for(scanf("%d%d",&n,&p);n|p;scanf("%d%d",&n,&p))
    		Init(),Read(),Dfs(p),Get_Ans();
    	return 0;
    }
    
  • 相关阅读:
    谈谈ios内存管理--持续更新
    IOS整体框架介绍
    OC-精简解读 block
    解读自定义UICollectionViewLayout--感动了我自己
    内存管理-深浅拷贝之 copy和mutableCopy
    OC-socket使用介绍
    ios 调用系统打电话和发消息的功能
    Swift-扩展
    Java 之switch语句
    Java 键盘输入数据
  • 原文地址:https://www.cnblogs.com/hihocoder/p/12077994.html
Copyright © 2011-2022 走看看