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 }
原文地址:https://www.cnblogs.com/fightfordream/p/6035598.html