[bzoj4240] 有趣的家庭菜园

  还是膜网上题解QAQ

  从低到高考虑,这样就不会影响后挪的草了。

  每次把草贪心地挪到代价较小的一边。位置为i的草,花费为min( 1..i-1中更高的草的数目,i+1..n中更高的草的数目 )

  因为更小的草已经被挪到两边了..所以代价就是更高的草的数目。

  拿个树状数组统计一下就好了。

 #include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
const int maxn=;
struct zs{int v,id;}a[maxn];
int mp[maxn],t[maxn],t1[maxn];
ll ans;
int i,j,k,n,m,cnt; int ra;char rx;
inline int read(){
rx=getchar(),ra=;
while(rx<''||rx>'')rx=getchar();
while(rx>=''&&rx<='')ra=ra*+rx-,rx=getchar();return ra;
}
bool cmp(zs a,zs b){return a.v<b.v;}
int main(){
n=read();register int j;int x,y;
for(i=;i<=n;i++)a[i].v=read(),a[i].id=i;
sort(a+,a++n,cmp);
for(i=;i<=n;mp[a[i].id]=cnt,i++)cnt+=a[i].v!=a[i-].v;
for(i=;i<=n;i++){
j=mp[i];while(j<=cnt)t1[j]++,j+=j&-j;
}
for(i=n;i>;i--){
j=mp[i];while(j<=cnt)t1[j]--,j+=j&-j;
x=n-i,y=i-;
j=mp[i];while(j)x-=t[j],y-=t1[j],j-=j&-j;
ans+=x<y?x:y;
j=mp[i];while(j<=cnt)t[j]++,j+=j&-j;
}
printf("%lld\n",ans);
}
上一篇:kaggle-泰坦尼克号Titanic-2


下一篇:C++:memset ,memcpy 和strcpy 的根本区别!