zoukankan      html  css  js  c++  java
  • Counting Offspring(hdu3887)

    Counting Offspring

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


    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
    思路:dfs序+线段树;
    首先dfs序线性化,然后我们知道,如果某点是另个点的孩子节点,那么他必然在被另一个点的父亲节点所包括,所以从小到大查询[l[i],r[i]]区间的和,往线段树加点单点更新。复杂度n*log(n);
     1 #include<stdio.h>
     2 #include<algorithm>
     3 #include<queue>
     4 #include<stdlib.h>
     5 #include<iostream>
     6 #include<string.h>
     7 #include<set>
     8 #include<map>
     9 #include<vector>
    10 using namespace std;
    11 typedef long long LL;
    12 typedef vector<int>Ve;
    13 vector<Ve>vec(100005);
    14 bool flag[100005];
    15 int l[100005];
    16 int r[100005];
    17 int id[100005];
    18 int cn = 0;
    19 void dfs(int n);
    20 
    21 int tree[100005*4];
    22 void up(int l,int r,int k,int nn,int mm);
    23 int ask(int l,int r,int k,int nn,int mm);
    24 int main(void)
    25 {
    26     int n,p;
    27     while(scanf("%d %d",&n,&p),n!=0&&p!=0)
    28     {   cn = 0;
    29         for(int i = 0;i < 100005;i++)
    30             vec[i].clear();
    31         memset(flag,0,sizeof(flag));
    32         for(int i = 0;i < n-1;i++)
    33         {
    34             int x,y;
    35             scanf("%d %d",&x,&y);
    36             vec[x].push_back(y);
    37             vec[y].push_back(x);
    38         }
    39         dfs(p);
    40         memset(tree,0,sizeof(tree));
    41         for(int i = 1;i <= n;i++)
    42         {
    43             if(i == 1)
    44                 printf("%d",ask(l[i],r[i],0,1,cn));
    45                 else printf(" %d",ask(l[i],r[i],0,1,cn));
    46             up(l[i],l[i],0,1,cn);
    47         }
    48         printf("
    ");
    49     }
    50     return 0;
    51 }
    52 void dfs(int n)
    53 {
    54     flag[n] = true;
    55     l[n] = ++cn;
    56     for(int i = 0;i < vec[n].size();i++)
    57     {
    58         int d = vec[n][i];
    59         if(!flag[d])
    60             dfs(d);
    61     }r[n] = cn;
    62 }
    63 void up(int l,int r,int k,int nn,int mm)
    64 {
    65     if(l > mm||r < nn)
    66     {
    67         return ;
    68     }
    69     else if(l <= nn&&r >= mm)
    70     {
    71         tree[k]++;return ;
    72     }
    73     up(l,r,2*k+1,nn,(nn+mm)/2);
    74     up(l,r,2*k+2,(nn+mm)/2+1,mm);
    75     tree[k] = tree[2*k+1]+tree[2*k+2];
    76 }
    77 int ask(int l,int r,int k,int nn,int mm)
    78 {
    79     if(l > mm||r < nn)
    80     {
    81         return 0;
    82     }
    83     else if(l <= nn&&r >= mm)
    84     {
    85         return tree[k];
    86     }
    87     else
    88     {
    89         int nx = ask(l,r,2*k+1,nn,(nn+mm)/2);
    90         int ny = ask(l,r,2*k+2,(nn+mm)/2+1,mm);
    91         return nx + ny;
    92     }
    93 }
     
    Sample Output
    0 0 0 0 0 1 6 0 3 1 0 0 0 2 0
     
  • 相关阅读:
    vim 末行模式简单练习
    末行模式
    vim 简单用法
    sed用法
    在原有的基础之上,启用NAT模型
    启用隔离模型
    一个前端的自我修养
    如何提升我的HTML&CSS技术,编写有结构的代码
    MVC缓存
    MVC分页
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/6424124.html
Copyright © 2011-2022 走看看