• HDU 3887:Counting Offspring(DFS序+树状数组)


    http://acm.hdu.edu.cn/showproblem.php?pid=3887

    题意:给出一个有根树,问对于每一个节点它的子树中有多少个节点的值是小于它的。

    思路:这题和那道苹果树是一样的,DFS序+树状数组,一开始没想到,用了DFS序+排序,结果超时了。在in和out之间的时间戳是该节点子树的范围,从后往前扫,再删掉大的,这样可以满足值小于该节点的条件。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cmath>
     4 #include <cstdlib>
     5 #include <algorithm>
     6 #include <string>
     7 #include <iostream>
     8 #include <stack>
     9 #include <map>
    10 #include <queue>
    11 using namespace std;
    12 #define N 100010
    13 #define INF 0x3f3f3f3f
    14 struct node
    15 {
    16     int v, nxt;
    17 }edge[N*2];
    18 int bit[N*2], n, tot, head[N], tim, in[N], out[N], ans[N];
    19 
    20 void add(int u, int v)
    21 {
    22     edge[tot].v = v; edge[tot].nxt = head[u]; head[u] = tot++;
    23 }
    24 
    25 void dfs(int u, int fa)
    26 {
    27     in[u] = ++tim;
    28     for(int i = head[u]; ~i; i = edge[i].nxt) {
    29         int v = edge[i].v;
    30         if(v == fa) continue;
    31         dfs(v, u);
    32     }
    33     out[u] = tim;
    34 }
    35 
    36 int lowbit(int x)
    37 {
    38     return x & (-x);
    39 }
    40 
    41 void update(int x, int val)
    42 {
    43     while(x <= tim) {
    44         bit[x] += val;
    45         x += lowbit(x);
    46     }
    47 }
    48 
    49 int query(int x)
    50 {
    51     int ans = 0;
    52     while(x) {
    53         ans += bit[x];
    54         x -= lowbit(x);
    55     }
    56     return ans;
    57 }
    58 
    59 int main()
    60 {
    61     int rt;
    62     while(scanf("%d%d", &n, &rt), n + rt) {
    63         memset(head, -1, sizeof(head));
    64         memset(bit, 0, sizeof(bit));
    65         tot = tim = 0;
    66         for(int i = 1; i < n; i++) {
    67             int u, v;
    68             scanf("%d%d", &u, &v);
    69             add(u, v); add(v, u);
    70         }
    71         dfs(rt, -1);
    72         for(int i = 1; i <= n; i++) update(i, 1);
    73         for(int i = n; i >= 1; i--) {
    74             ans[i] = query(out[i]) - query(in[i]);
    75             update(in[i], -1); 
    76         }
    77         for(int i = 1; i <= n; i++) {
    78             if(i == n) printf("%d
    ", ans[i]);
    79             else printf("%d ", ans[i]);
    80         }
    81     }
    82     return 0;
    83 }
  • 相关阅读:
    js replace替换 忽略大小写问题
    Spring security实现国际化问题
    Mac 的mysql5.7没有配置文件,如何解决only_full_group_by 问题
    java设计模式学习
    synchronized的锁问题
    理解java的三种代理模式
    [acm]HDOJ 2059 龟兔赛跑
    [acm]HDOJ 2673 shǎ崽 OrOrOrOrz
    [acm]HDOJ 1200 To and Fro
    [acm]HDOJ 2064 汉诺塔III
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6035598.html
Copyright © 2020-2023  润新知