每個小朋友都有一個不高興的程度。開始的時候,所有小朋友的不高興程度都是0。
如果某個小朋友第一次被要求交換,則他的不高興程度增加1,如果第二次要求他交換,則他的不高興程度增加2(即不高興程度爲3),依次類推。當要求某個小朋友第k次交換時,他的不高興程度增加k。
請問,要讓所有小朋友按從低到高排隊,他們的不高興程度之和最小是多少。
如果有兩個小朋友身高一樣,則他們誰站在誰前面是沒有關係的。
第二行包含 n 個整數 H1 H2 … Hn,分別表示每個小朋友的身高。
3 2 1
解題思路:一個數最少的交換次數就是前面比它大的數+後面比它小的數;
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 1000010
int n;
__int64 c[maxn+20];
int num[100010];
__int64 cnt[100010];
int lowbit(int x)
{
return x&(-x);
}
int updata(int x)
{
while(x<=maxn)
{
c[x]+=1;
x+=lowbit(x);
}
}
int sum(int x)
{
int ans=0;
while(x>0)
{
ans+=c[x];
x-=lowbit(x);
}
return ans;
}
int main()
{
memset(c,0,sizeof(c));
memset(cnt,0,sizeof(cnt));
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&num[i]);
for(int i=0;i<n;i++)
{
cnt[i]+=i-sum(num[i]+1);
updata(num[i]+1);
}
memset(c,0,sizeof(c));
for(int i=n-1;i>=0;i--)
{
cnt[i]+=sum(num[i]);
updata(num[i]+1);
}
__int64 ans=0;
for(int i=0;i<n;i++)
ans+=(cnt[i]*(cnt[i]+1)/2);
printf("%I64d\n",ans);
}