[Usaco2017 Jan]Balanced Photo
作者:互联网
题目
Description
农夫约翰正在安排他的N头牛拍照片, 每头牛有一个身高,从1到N编号,排列成一行(h1,h2...hn),每头牛i左边比他高的牛的数量记为Li,
右边比他高的牛的数量记为Ri,如果存在i满足max(Ri,Li)>2*min(Li,Ri)则这个牛i是不平衡的,现在FJ需要你告诉他有多少头牛不平衡。
Input
输入第一行为N(N<=1e5)
接下来的一行有N个数,每个数表示第i头牛的身高,不超过1e9
Output
输出有多少头牛是不平衡的
Sample Input
7 34 6 23 0 5 99 2
Sample Output
3
下面链接教你怎么求在a前面比a小的数数量(如果不会一定要看,与题目有关)
https://www.cnblogs.com/wzx-RS-STHN/p/13193271.html
思路:
看了链接后,我们已经知道了怎么求有多少个数在a前面的数比a小;
我们定义x=多少个数在a前面的数比a小
那么多少个数在a前面的数比a大;当前 枚举到的位置-x;
然后多少个数在a后面的数比a大,则逆循环,反之;
代码:
#include<bits/stdc++.h> typedef long long ll; using namespace std; inline ll read() { ll a=0,ha=1; char c=getchar(); while (c<'0'||c>'9') {if (c=='-') ha=-1; c=getchar();} while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();} return a*ha; } ll n,m,sum[1000010],b[1000010]; ll L[1000010],R[1000010]; struct oh { ll v,num; }a[1000010]; inline ll lowbit(ll x) { return x&(-x); } inline void insert(ll x,ll y)//加入 { while(x<=n) { sum[x]+=y; x+=lowbit(x); } } inline ll findout(ll x)//查找 { ll ans=0; while(x) { ans+=sum[x]; x-=lowbit(x); } return ans; } inline ll cmp(oh a,oh b)//排序 { if(a.v==b.v) return a.num<b.num; else return a.v<b.v; } int main() { n=read(); //离散化 for(ll i=1;i<=n;i++) { a[i].v=read(); a[i].num=i;//将每一个数的位置记下 } sort(a+1,a+n+1,cmp);//从小到大排序, //这样每个数都有顺序了,并且每个数对应的位置没有改变 for(ll i=1;i<=n;i++) b[a[i].num]=i;//把第i小的数位置上赋值为i //cout<<endl; //for(ll i=1;i<=n;i++) // cout<<b[i]<<endl; for(ll i=1;i<=n;i++) { ll x=findout(b[i]); L[i]=i-x-1;//左边比他大的牛数量 insert(b[i],1); } memset(sum,0,sizeof(sum)); for(ll i=n;i>=1;i--) { ll x=findout(b[i]); R[i]=n-i-x;//反之 insert(b[i],1); } ll ans=0; for(ll i=1;i<=n;i++) { //cout<<R[i]<<" "<<L[i]<<endl; ll mx=max(R[i],L[i]); ll mn=min(R[i],L[i]); if(mx>2*mn) ans++; } printf("%lld\n",ans); }
农夫约翰正在安排他的N头牛拍照片, 每头牛有一个身高,从1到N编号,排列成一行(h1,h2...hn),每头牛i左边比他高的牛的数量记为Li,右边比他高的牛的数量记为Ri,如果存在i满足max(Ri,Li)>2*min(Li,Ri)则这个牛i是不平衡的,现在FJ需要你告诉他有多少头牛不平衡。
标签:Usaco2017,头牛,数比,ll,个数,Li,Jan,Balanced,Ri 来源: https://www.cnblogs.com/wzx-RS-STHN/p/13193350.html