【bzoj4240】有趣的家庭菜园
只要统计每一个左右分别有多少比他高的去min,然后求和
#include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> using namespace std; typedef long long LL; #define lowbit(x) (x & (-x)) #define N 300010 struct Node { int h,id; }a[N]; int n; int cnt; LL ans; int c[N]; int read() { int x=0; char ch=getchar(); while (ch<'0' || ch>'9') ch=getchar(); while (ch>='0' && ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x; } bool cmp(Node x,Node y) { return x.h>y.h; } void add(int x) { while (x<=n) c[x]++,x+=lowbit(x); } int query(int x) { int res(0); while (x) res+=c[x],x-=lowbit(x); return res; } int main() { n=read(); for (int i=1;i<=n;i++) a[i].h=read(),a[i].id=i; sort(a+1,a+n+1,cmp); int k=1; for (int i=1;i<=n;i++) { if (a[i].h!=a[i-1].h) while (k<i) add(a[k++].id); cnt=query(a[i].id); ans+=min(cnt,k-1-cnt); } printf("%lld",ans); return 0; }