首页 > 代码库 > Hdu 3887树状数组+模拟栈
Hdu 3887树状数组+模拟栈
题目链接
Counting Offspring
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1757 Accepted Submission(s): 582Problem DescriptionYou 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.
InputMultiple 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.
OutputFor each test case, output n integer in one line representing f(1), f(2) … f(n), separated by a space.
Sample Input15 77 107 17 97 37 410 1414 214 139 119 66 56 83 153 120 0
Sample Output0 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 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。