题目链接

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:
 /*************************************************************************
> File Name: 3887.cpp
> Author: Stomach_ache
> Mail: sudaweitong@gmail.com
> Created Time: 2014年08月09日 星期六 14时11分33秒
> Propose:
************************************************************************/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cmath>
#include <string>
#include <cstdio>
#include <vector>
#include <fstream>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = ;
int n, p;
int ans[maxn], c[maxn], tmp[maxn];
bool vis[maxn];
vector<int> g[maxn]; int lowbit(int x) {
return x & -x;
} int sum(int x) {
int res = ;
while (x > ) {
res += c[x];
x -= lowbit(x);
}
return res;
} void add(int x, int v) {
while (x <= n) {
c[x] += v;
x += lowbit(x);
}
} void dfs(int u, int fa) {
tmp[u] = sum(u-);
for (int i = ; i < (int)g[u].size(); i++) {
int v = g[u][i];
if (v == fa) continue;
add(v, );
dfs(v, u);
}
ans[u] = sum(u-) - tmp[u];
} int main(void) {
while (~scanf("%d %d", &n, &p)) {
if (n == && p == ) return ;
for (int i = ; i <= n; i++) g[i].clear();
int x, y;
for (int i = ; i < n; i++) {
scanf("%d %d", &x, &y);
g[x].push_back(y);
g[y].push_back(x);
}
memset(c, , sizeof(c));
dfs(p, -);
for (int i = ; i <= n; i++)
printf("%d%c", ans[i], i == n ? '\n' : ' ');
}
return ;
}

附上模拟栈的AC代码:

 /*************************************************************************
> File Name: 3887.cpp
> Author: Stomach_ache
> Mail: sudaweitong@gmail.com
> Created Time: 2014年08月09日 星期六 14时11分33秒
> Propose:
************************************************************************/
#include <stack>
#include <cmath>
#include <string>
#include <cstdio>
#include <vector>
#include <fstream>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = ;
int n, p;
int ans[maxn], c[maxn*], l[maxn], r[maxn], cur[maxn];
int len;
bool vis[maxn];
vector<int> g[maxn];
stack<int> S; int lowbit(int x) {
return x & -x;
} int sum(int x) {
int res = ;
while (x > ) {
res += c[x];
x -= lowbit(x);
}
return res;
} void add(int x, int v) {
while (x <= len) {
c[x] += v;
x += lowbit(x);
}
} void dfs(int u) {
memset(vis, false, sizeof(vis));
memset(cur, , sizeof(cur));
while (!S.empty()) S.pop();
S.push(u);
len = ;
while (!S.empty()) {
int now = S.top();
if (!vis[now]) {
vis[now] = true;
l[now] = ++len;
}
bool flag = false;
for (int& i = cur[now]; i < (int)g[now].size(); i++) {
int v = g[now][i];
if (!vis[v]) {
S.push(v);
flag = true;
break;
}
}
if (flag) continue;
if (vis[now]) {
r[now] = ++len;
S.pop();
}
}
} int main(void) {
while (~scanf("%d %d", &n, &p)) {
if (n == && p == ) return ;
for (int i = ; i <= n; i++) g[i].clear();
int x, y;
for (int i = ; i < n; i++) {
scanf("%d %d", &x, &y);
g[x].push_back(y);
g[y].push_back(x);
}
memset(c, , sizeof(c));
dfs(p);
for (int i = ; i <= n; i++) {
ans[i] = sum(r[i]-) - sum(l[i]);
add(l[i], );
}
for (int i = ; i <= n; i++)
printf("%d%c", ans[i], i == n ? '\n' : ' ');
}
return ;
}

Hdu 3887树状数组+模拟栈的更多相关文章

  1. hdu 4638 树状数组 区间内连续区间的个数(尽可能长)

    Group Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...

  2. hdu 4777 树状数组+合数分解

    Rabbit Kingdom Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  3. HDU 3887 Counting Offspring (树状数组+人工模拟栈)

    对这棵树DFS遍历一遍,同一节点入栈和出栈之间访问的节点就是这个节点的子树. 因此节点入栈时求一次 小于 i 的节点个数 和,出栈时求一次 小于 i 的节点个数 和,两次之差就是答案. PS.这题直接 ...

  4. HDU 2852 (树状数组+无序第K小)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2852 题目大意:操作①:往盒子里放一个数.操作②:从盒子里扔掉一个数.操作③:查询盒子里大于a的第K小 ...

  5. HDU 4911 (树状数组+逆序数)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4911 题目大意:最多可以交换K次,就最小逆序对数 解题思路: 逆序数定理,当逆序对数大于0时,若ak ...

  6. hdu 5792(树状数组,容斥) World is Exploding

    hdu 5792 要找的无非就是一个上升的仅有两个的序列和一个下降的仅有两个的序列,按照容斥的思想,肯定就是所有的上升的乘以所有的下降的,然后再减去重复的情况. 先用树状数组求出lx[i](在第 i ...

  7. HDU 1934 树状数组 也可以用线段树

    http://acm.hdu.edu.cn/showproblem.php?pid=1394 或者是我自己挂的专题http://acm.hust.edu.cn/vjudge/contest/view. ...

  8. 2018 CCPC网络赛 1010 hdu 6447 ( 树状数组优化dp)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=6447 思路:很容易推得dp转移公式:dp[i][j] = max(dp[i][j-1],dp[i-1][j ...

  9. 【模板】HDU 1541 树状数组

    http://acm.hdu.edu.cn/showproblem.php?pid=1541 题意:给你一堆点,每个点右一个level,为其右下方所有点的数量之和,求各个level包含的点数. 题解: ...

随机推荐

  1. 【LGP5112】FZOUTSY

    题目 如果是\(hash\)做法的话显然就是把每一个位置后面的\(k\)个位置的hash值拿出来做一个莫队板子就好了 考虑一下牛逼的\(SAM\) 我们完全可以构造出来一棵后缀树,对于每个点找到其祖先 ...

  2. .NET Framework的属性类对控件的支持功能

     ToolBoxItem 此属性为类特性.属于工具箱属性,可以设置当前控件是否在工具箱中显示,以及所在工具箱项的类型名称等信息.默认生成的控件都显示在工具箱中. 更多设计时属性介绍: 4.3 属性的 ...

  3. 解决使用mybatis模糊查询为空的问题

    解决方法: 在数据库配置的url后添加?useUnicode=true&characterEncoding=utf-8 参考: https://blog.csdn.net/IT_private ...

  4. Luogu P1850 换教室(期望dp)

    P1850 换教室 题意 题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有\(2n\)节课程安排在\(n\)个时间段上.在第\(i(1\l ...

  5. windows API 第 18篇 FindFirstVolume FindNextVolume

    函数定义:Retrieves the name of a volume on a computer. FindFirstVolume is used to begin scanning the vol ...

  6. 廖雪峰Java11多线程编程-1线程的概念-1多线程简介

    多任务 现代操作系统(windows,MacOS,Linux)都可以执行多任务: 多任务就是同时运行多个任务,例如同时开启钉钉.百度网盘.火狐.谷歌.ps等 操作系统执行多任务就是让多个任务交替执行, ...

  7. #pragma omp parallel for

    #pragma omp parallel for是OpenMP中的一个指令,表示接下来的for循环将被多线程执行,另外每次循环之间不能有关系.示例如下: int main(int argc, char ...

  8. python 日记 day4

    1.为何数据要分类 数据是用来表示状态的,不同的状态应该用不同类型的数据来表示. 2.数据类型 数字 字符串 列表 元组 字典 集合 列表:列表相比于字符串,不仅可以储存不同的数据类型,而且可以储存大 ...

  9. pycharm 汉化补丁

    找了很久,找到了这个比较好的pycharm汉化补丁包,就分享出来 1. 将解压包解压出来 2 . 复制对应的汉化补丁包到 x:\xxx\JetBrains\PyCharm Community Edit ...

  10. MySql存储过程批量删除多个数据库中同名表中的指定字段

    1. 创建存储过程batchDeleteField:删除所有名称为"MyDB_"开头的数据库中的指定字段 -- ---------------------------- -- Pr ...