HDU 3887 Counting Offspring(dfs序 + 树状数组)
2015-09-22 15:26
561 查看
Counting Offspring
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2201 Accepted Submission(s): 738
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
Author
bnugong
Source
2011 Multi-University Training Contest 5 - Host
by BNU
解题思路:
求每个节点的字数中,标号比它小的点的个数,通过dfs转化为序列,然后用树状数组求解。与上一题类似,不过dfs过程中保存的东西不一样,本题保存的是所有点的标号,上一题保存的是每个点的进入时间和离开时间。
#include <iostream> #include <cstdio> #include <cstdlib> #include <vector> #include <cstring> using namespace std; const int MAXN = 100000 + 10; struct Edge{int to, next;}edge[MAXN<<1]; int tot, head[MAXN], n, root, dfs_clock, p[MAXN<<1], vis[MAXN],C[MAXN<<1], u, v, f[MAXN]; int H[MAXN]; void init() { tot = 0; memset(head, -1, sizeof(head)); dfs_clock = 0; memset(vis, 0, sizeof(vis)); memset(C, 0, sizeof(C)); } void addedge(int u, int v) { edge[tot].to = v; edge[tot].next = head[u]; head[u] = tot++; } void dfs(int x) { if(vis[x]) return ; vis[x] = 1; p[dfs_clock++] = x; for(int i=head[x];i!=-1;i=edge[i].next) { int v = edge[i].to; if(!vis[v]) dfs(v); } p[dfs_clock++] = x; } void add(int x, int d) { while(x <= 2 * n){C[x] += d; x += x & -x;} } int sum(int x) { int rs = 0; while(x){rs += C[x]; x -= x & -x;} return rs; } int main() { while(scanf("%d%d", &n, &root)!=EOF) { if(n == 0 && root == 0) break; init(); for(int i=1;i<n;i++) { scanf("%d%d", &u, &v); addedge(u, v); addedge(v, u); } dfs(root); for(int i=0;i<=n;i++) H[i] = -1; for(int i=0;i<dfs_clock;i++) { if(H[p[i]] != -1) f[p[i]] = sum(p[i] - 1) - H[p[i]]; else { H[p[i]] = sum(p[i] - 1); add(p[i], 1); } } for(int i=1;i<n;i++) cout << f[i] << ' '; cout << f << endl; } return 0; } /* 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 */
相关文章推荐
- eclipse中提高编程效率的快捷键
- Java Servlet API中文说明文档
- java学习笔记面向对象
- maven 下载 源码和javadoc命令
- test5.14
- Java -- Matrix的一点认识
- JVM源码分析之javaagent原理完全解读
- Java总结篇系列:类型转换/造型
- test5.13
- ubuntu 安装JDK
- Springmvc中@RequestParam传值中文乱码解决方案
- eclipse install new software 不见了
- spring mvc 跨域请求处理——spring 4.2 以上
- instanceof和 Class.isInstance
- 让Java代码更高效
- Java 注解
- 深入分析Java ClassLoader原理
- java.util.concurrent之Semaphore
- HBase搭建并使用Java调用HBaseAPI
- spring mvc 事务不生效 不回滚