【bzoj4756】[Usaco2017 Jan]Promotion Counting 离散化+树状数组

原文地址:http://www.cnblogs.com/GXZlegend/p/6832263.html



题目描述

The cows have once again tried to form a startup company, failing to remember from past experience that cows make terrible managers!The cows, conveniently numbered 1…N1…N (1≤N≤100,000), organize the company as a tree, with cow 1 as the president (the root of the tree). Each cow except the president has a single manager (its "parent" in the tree). Each cow ii has a distinct proficiency rating, p(i), which describes how good she is at her job. If cow ii is an ancestor (e.g., a manager of a manager of a manager) of cow jj, then we say jj is a subordinate of ii.

Unfortunately, the cows find that it is often the case that a manager has less proficiency than several of her subordinates, in which case the manager should consider promoting some of her subordinates. Your task is to help the cows figure out when this is happening. For each cow ii in the company, please count the number of subordinates jj where p(j)>p(i).

n只奶牛构成了一个树形的公司,每个奶牛有一个能力值pi,1号奶牛为树根。
问对于每个奶牛来说,它的子树中有几个能力值比它大的。

输入

The first line of input contains N

The next N lines of input contain the proficiency ratings p(1)…p(N)

for the cows. Each is a distinct integer in the range 1…1,000,000,000

The next N-1 lines describe the manager (parent) for cows 2…N

Recall that cow 1 has no manager, being the president.

n,表示有几只奶牛 n<=100000
接下来n行为1-n号奶牛的能力值pi
接下来n-1行为2-n号奶牛的经理(树中的父亲)

输出

Please print N lines of output. The ith line of output should tell the number of

subordinates of cow ii with higher proficiency than cow i.

共n行,每行输出奶牛i的下属中有几个能力值比i大

样例输入

5

804289384

846930887

681692778

714636916

957747794

1

1

2

3

样例输出

2

0

1

0

0



题解

离散化+树状数组

先将数据离散化,然后在树上dfs。

搜子树之前求一下比w[x]小的数的个数,搜子树之后再求一下比w[x]小的数的个数,作差即为子树中比w[x]小的数的个数。最后把w[x]加入到树状数组中。

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100010
using namespace std;
struct data
{
	int w , id;
}a[N];
int n , v[N] , pos[N] , f[N] , ans[N] , head[N] , to[N] , next[N] , cnt;
void add(int x , int y)
{
	to[++cnt] = y , next[cnt] = head[x] , head[x] = cnt;
}
bool cmp(data a , data b)
{
	return a.w < b.w;
}
void update(int x , int a)
{
	int i;
	for(i = x ; i <= n ; i += i & -i) f[i] += a;
}
int query(int x)
{
	int i , ans = 0;
	for(i = x ; i ; i -= i & -i) ans += f[i];
	return ans;
}
void dfs(int x)
{
	int i;
	ans[x] -= query(v[x]);
	for(i = head[x] ; i ; i = next[i]) dfs(to[i]);
	ans[x] += query(v[x]);
	update(v[x] , 1);
}
int main()
{
	int i , x;
	scanf("%d" , &n);
	for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &a[i].w) , a[i].id = i;
	sort(a + 1 , a + n + 1 , cmp);
	for(i = 1 ; i <= n ; i ++ ) v[a[i].id] = n - i + 1;
	for(i = 2 ; i <= n ; i ++ ) scanf("%d" , &x) , add(x , i);
	dfs(1);
	for(i = 1 ; i <= n ; i ++ ) printf("%d\n" , ans[i]);
	return 0;
}
时间: 2024-11-11 00:36:10

【bzoj4756】[Usaco2017 Jan]Promotion Counting 离散化+树状数组的相关文章

[BZOJ4756][Usaco2017 Jan]Promotion Counting 树状数组

4756: [Usaco2017 Jan]Promotion Counting Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 305  Solved: 217[Submit][Status][Discuss] Description The cows have once again tried to form a startup company, failing to remember from past experience t hat cow

poj 2299 Ultra-QuickSort 离散化 + 树状数组

题目链接:http://poj.org/problem?id=2299 离散化 + 树状数组 教科书例题般的题目 #include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <cmath> #include <vector> #include <stack> #include <set> #include

hdu 3015 Disharmony Trees (离散化+树状数组)

Disharmony Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 663    Accepted Submission(s): 307 Problem Description One day Sophia finds a very big square. There are n trees in the square. T

CodeForces 540E - Infinite Inversions(离散化+树状数组)

花了近5个小时,改的乱七八糟,终于A了. 一个无限数列,1,2,3,4,...,n....,给n个数对<i,j>把数列的i,j两个元素做交换.求交换后数列的逆序对数. 很容易想到离散化+树状数组,但是发现那些没有交换的数也会产生逆序对数,但我没有算. 经明神提示, 把没有用到的数字段化成点.然后用树状数组算一下就好了. 然后我用一个数组记录每个点的长度.比如 <1,2><5,6>,1,2,3,4,5,6只有1,2,5,6用到了,那么离散化为1,2,3,4,5,f[1]=

hdu 3030 Increasing Speed Limits (离散化+树状数组+DP思想)

Increasing Speed Limits Time Limit: 2000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 481    Accepted Submission(s): 245 Problem Description You were driving along a highway when you got caught by the road p

POJ 2299 Ultra-QuickSort (离散化+树状数组)

题目链接:POJ 2299 Ultra-QuickSort 求一串序列相邻连个元素交换多少后,是一串上升的序列. 思路:求该串序列的逆序数,数据比较大,要离散化. AC代码: #include<stdio.h> #include<string.h> #include<set> #include<map> #include<algorithm> #define ll __int64 using namespace std; const ll max

2018中国大学生程序设计竞赛 - 网络选拔赛 1010 YJJ&#39;s Salesman 【离散化+树状数组维护区间最大值】

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6447 YJJ's Salesman Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 919    Accepted Submission(s): 290 Problem Description YJJ is a salesman who h

sdut2610---Boring Counting(离线+树状数组+离散化)

Boring Counting Time Limit: 3000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 In this problem you are given a number sequence P consisting of N integer and Pi is the ith element in the sequence. Now you task is to answer a list of queries, for each query,

HDU 4358 Boring counting(树状数组)

题意:  给定一棵树,每个节点有一个点权,然后有一些询问,求以某个点为根的子树中有多少的数出现了恰好k次. 思路: 首先dfs一次将树形结构转化成线性结构,利用时间戳记录下以结点u为根的子树在数组中的开始位置和结束位置. 那么我们将所有查询记录下来离线来做,将所有的查询按右端点升序排序. 考虑用树状数组来做这道题,每个位置记录当前从1到当前位置有多少数出现了恰好k次. 从头遍历一遍数组,map离散化记录每个值出现的位置,对于每个位置,如果值出现的次数t大于k,那么在将第t-k次出现的位置加一