每個小朋友都有一個不高興的程度。開始的時候,所有小朋友的不高興程度都是0。
如果某個小朋友第一次被要求交換,則他的不高興程度增加1,如果第二次要求他交換,則他的不高興程度增加2(即不高興程度爲3),依次類推。當要求某個小朋友第k次交換時,他的不高興程度增加k。
請問,要讓所有小朋友按從低到高排隊,他們的不高興程度之和最小是多少。
如果有兩個小朋友身高一樣,則他們誰站在誰前面是沒有關係的。
第二行包含 n 個整數 H1 H2 … Hn,分別表示每個小朋友的身高。
3 2 1
對於30%的數據, 1<=n<=1000;
對於50%的數據, 1<=n<=10000;
對於100%的數據,1<=n<=100000,0<=Hi<=1000000。
#include <iostream> #include <cstring> #include <algorithm> #include <cstdio> #define N 100010 using namespace std; long long a[N],c[N*10],n; long long d[N]; int low_bit(int x) { return x&(x^(x-1)); } void update(int x,int y) { for(int i=x;i<=N*10-1;i+=low_bit(i)) c[i]+=y; } int Sum(int x) { int sum=0; for(int i=x;i>0;i-=low_bit(i)) sum+=c[i]; return sum; } int main() { long long ans=0; scanf("%d",&n); memset(c,0,sizeof(c)); memset(d,0,sizeof(d)); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); update(a[i]+1,1); d[i]=i-Sum(a[i]+1); //右邊的逆序對 } memset(c,0,sizeof(c)); for(int i=n;i>0;i--) { update(a[i]+1,1); d[i]+=Sum(a[i]); //左邊的逆序對 } for(int i=1;i<=n;i++) { ans=ans+d[i]*(d[i]+1)/2; } cout<<ans<<endl; return 0; }