这个题目n^2的算法显而易见,现在考虑怎么优化。实际就是求区间1-i中,i排第几大,也就是前面比他小的数有几个,那么这个问题就转化为逆序对问题,而逆序对的做法树状数组最好写了。先要离散化,题目中要求左面比他高,倒着离散化。的代码如下。
#include <iostream>
#include <cstdio>
#include<algorithm>
using namespace std;
const int maxn = 1e5+10;
int n,m,b[maxn],l,r,ans,t[maxn];
struct COW {
int v,id;
} a[maxn];
bool cmp(COW x,COW y) {
return x.v>y.v;
};
int lowbit(int x) {
return x&-x;
}
void update(int x,int v) {
for(; x<n; x+=lowbit(x))t[x]+=v;
}
int query(int x) { //查询比他小的数的个数 ,1.。x的个数 ,但因为排序是逆序的实际是比他大的个数
int ans=0;
for(; x; x-=lowbit(x))ans+=t[x];
return ans;
}
int main() {
scanf("%d",&n);
for(int i=1; i<=n; i++)scanf("%d",&a[i].v),a[i].id=i; //逆序排序后离散化
sort(a+1,a+1+n,cmp);
for(int i=1; i<=n; i++)b[a[i].id]=i;
for(int i=1; i<=n; i++) {
l=query(b[i]);
r=b[i]-l-1;
if((l*2<r)||(r*2<l))ans++;
update(b[i],1);
}
printf("%d\n",ans);
}