码迷,mamicode.com
首页 > 其他好文 > 详细

Hdu 3887树状数组+模拟栈

时间:2014-08-09 23:01:29      阅读:372      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   http   color   java   os   io   

题目链接

Counting Offspring

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


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
可以直接dfs(需要手工加栈)
Accepted Code:
 1 /*************************************************************************
 2     > File Name: 3887.cpp
 3     > Author: Stomach_ache
 4     > Mail: sudaweitong@gmail.com
 5     > Created Time: 2014年08月09日 星期六 14时11分33秒
 6     > Propose: 
 7  ************************************************************************/
 8 #pragma comment(linker, "/STACK:1024000000,1024000000")
 9 #include <cmath>
10 #include <string>
11 #include <cstdio>
12 #include <vector>
13 #include <fstream>
14 #include <cstring>
15 #include <iostream>
16 #include <algorithm>
17 using namespace std;
18 const int maxn = 100002;
19 int n, p;
20 int ans[maxn], c[maxn], tmp[maxn];
21 bool vis[maxn];
22 vector<int> g[maxn];
23 
24 int lowbit(int x) {
25       return x & -x;
26 }
27 
28 int sum(int x) {
29       int res = 0;
30     while (x > 0) {
31           res += c[x];
32         x -= lowbit(x);
33     }
34     return res;
35 }
36 
37 void add(int x, int v) {
38       while (x <= n) {
39           c[x] += v;
40         x += lowbit(x);
41     }
42 }
43 
44 void dfs(int u, int fa) {
45       tmp[u] = sum(u-1);
46     for (int i = 0; i < (int)g[u].size(); i++) {
47           int v = g[u][i];
48           if (v == fa) continue;
49           add(v, 1);
50           dfs(v, u);
51     }    
52     ans[u] = sum(u-1) - tmp[u];
53 }
54 
55 int main(void) {
56       while (~scanf("%d %d", &n, &p)) {
57           if (n == 0 && p == 0) return 0;
58           for (int i = 1; i <= n; i++) g[i].clear();
59         int x, y;
60         for (int i = 1; i < n; i++) {
61             scanf("%d %d", &x, &y);
62             g[x].push_back(y);
63             g[y].push_back(x);
64         }
65         memset(c, 0, sizeof(c));
66         dfs(p, -1);
67         for (int i = 1; i <= n; i++) 
68               printf("%d%c", ans[i], i == n ? \n :  );
69     }
70     return 0;
71 }

附上模拟栈的AC代码:

 1 /*************************************************************************
 2     > File Name: 3887.cpp
 3     > Author: Stomach_ache
 4     > Mail: sudaweitong@gmail.com
 5     > Created Time: 2014年08月09日 星期六 14时11分33秒
 6     > Propose: 
 7  ************************************************************************/
 8 #include <stack>
 9 #include <cmath>
10 #include <string>
11 #include <cstdio>
12 #include <vector>
13 #include <fstream>
14 #include <cstring>
15 #include <iostream>
16 #include <algorithm>
17 using namespace std;
18 const int maxn = 100002;
19 int n, p;
20 int ans[maxn], c[maxn*2], l[maxn], r[maxn], cur[maxn];
21 int len;
22 bool vis[maxn];
23 vector<int> g[maxn];
24 stack<int> S;
25 
26 int lowbit(int x) {
27       return x & -x;
28 }
29 
30 int sum(int x) {
31     int res = 0;
32     while (x > 0) {
33         res += c[x];
34         x -= lowbit(x);
35     }
36     return res;
37 }
38 
39 void add(int x, int v) {
40     while (x <= len) {
41         c[x] += v;
42         x += lowbit(x);
43     }
44 }
45 
46 void dfs(int u) {
47     memset(vis, false, sizeof(vis));
48     memset(cur, 0, sizeof(cur));
49     while (!S.empty()) S.pop();
50     S.push(u);
51     len = 0;
52     while (!S.empty()) {
53         int now = S.top();
54         if (!vis[now]) {
55             vis[now] = true;
56             l[now] = ++len;
57         }
58         bool flag = false;
59         for (int& i = cur[now]; i < (int)g[now].size(); i++) {
60               int v = g[now][i];
61               if (!vis[v]) {
62                 S.push(v);
63                 flag = true;
64                 break;
65             }
66         }
67         if (flag) continue;
68         if (vis[now]) {
69             r[now] = ++len;
70             S.pop();
71         }
72     }
73 }
74 
75 int main(void) {
76       while (~scanf("%d %d", &n, &p)) {
77         if (n == 0 && p == 0) return 0;
78         for (int i = 1; i <= n; i++) g[i].clear();
79         int x, y;
80         for (int i = 1; i < n; i++) {
81             scanf("%d %d", &x, &y);
82             g[x].push_back(y);
83             g[y].push_back(x);
84         }
85         memset(c, 0, sizeof(c));
86         dfs(p);
87         for (int i = 1; i <= n; i++) {
88             ans[i] = sum(r[i]-1) - sum(l[i]);
89             add(l[i], 1);
90         }
91         for (int i = 1; i <= n; i++) 
92             printf("%d%c", ans[i], i == n ? \n :  );
93     }
94     return 0;
95 }

 

Hdu 3887树状数组+模拟栈,布布扣,bubuko.com

Hdu 3887树状数组+模拟栈

标签:des   style   blog   http   color   java   os   io   

原文地址:http://www.cnblogs.com/Stomach-ache/p/3901652.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!