17暑期ACM俱乐部个人训练赛第2场 G Balanced Photo (树状数组)



问题 G: Balanced Photo

时间限制: 1 Sec  内存限制: 128 MB
提交: 89  解决: 36
[提交][状态][讨论版]

题目描述

Farmer John is arranging his N cows in a line to take a photo (1N100,000). The height of the ith cow in sequence ishi, and the heights of all cows are distinct. 
As with all photographs of his cows, FJ wants this one to come out looking as nice as possible. He decides that cow i looks "unbalanced" if Li and Ri differ by more than factor of 2, where Li and Ri are the number of cows taller than i on her left and right, respectively. That is, i is unbalanced if the larger of Li and Ri is strictly more than twice the smaller of these two numbers. FJ is hoping that not too many of his cows are unbalanced.

Please help FJ compute the total number of unbalanced cows.

输入

The first line of input contains N. The next N lines contain h1hN, each a nonnegative integer at most 1,000,000,000.

输出

Please output a count of the number of cows that are unbalanced.

样例输入

7

34

6

23
0

5

99

2

样例输出

3

题意:  一排牛 照相,   对于某一头牛x  如果左边比他高的个数 记为le[x]  右边比他高的个数为 ri[x]   如果max(le[x],ri[x])>min(le[x].ri[x])*2 

则这头牛 即为不平衡,  问这样的牛有多少头


先把牛的身高离散成等差1的序列;

用树状数组, 把所有n 的 左边和右边 描述出来,  最后找符合的个数


#include <stdio.h>
#include <queue>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N=101000;
int tree[N];
int a[N];
int n;
int le[N],ri[N];
struct node{
	int x,idex;
}pre[N];;
int cmp(node a,node b)
{
	if(a.x==b.x)
		return a.idex<b.idex;
	return a.x<b.x;
}
void add(int k,int num)
{
	while(k<=n)
	{
		tree[k]+=num;
		k+=k&-k;
	}
}
int Sum(int k)
{
	int sum=0;
	while(k)
	{
		sum+=tree[k];
		k-=k&-k;
	}
	return sum;
}
int main()
{
	while(~scanf("%d",&n))
	{
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&pre[i].x);
			pre[i].idex=i;
		}
		sort(pre+1,pre+n+1,cmp);
		for(int i=1;i<=n;i++)// 离散化成数字; 
			a[pre[i].idex]=i;
		memset(tree,0,sizeof(tree));
		for(int i=1;i<=n;i++)// 找左边比它大的数 
		{
			add(a[i],1);
			le[i]=i-Sum(a[i]);
		}
		memset(tree,0,sizeof(tree));
		for(int i=n;i>=1;i--)// 右边 
		{
			add(a[i],1);
			ri[i]=n-i+1-Sum(a[i]);
		}
		int ans=0;
		for(int i=1;i<=n;i++)
		{
			if(max(le[i],ri[i])>2*min(le[i],ri[i]))
				ans++;
		}
		printf("%d\n",ans);
	}
	return 0;
}


posted @ 2017-07-28 11:03  Sizaif  阅读(158)  评论(0编辑  收藏  举报