假设某同学左边以后x个比他高的,右边有y个比他矮的,那么他一共交换k=x+y次。又可知不高性值和次数成一个前n项和关系。
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <cstdio>
#include <string>
#include <stack>
#include <set>
#define IOS ios::sync_with_stdio(false), cin.tie(0)
using namespace std;
typedef long long ll;
ll c[1000010];
ll a[100010];
ll left_s[100010];
ll maxn=0;
ll lowbit(ll pos){
return pos&(-pos);
}
void insert(ll pos){
while(pos<=maxn){
c[pos]+=1;
pos+=lowbit(pos);
}
}
ll getsum(ll pos){
ll sum=0;
while(pos>0){
sum+=c[pos];
pos-=lowbit(pos);
}
return sum;
}
int main()
{
IOS;
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
maxn=max(maxn,++a[i]);
}
ll right=0;
ll ans=0;
//求左边比其大的数个数
memset(c,0,sizeof(c));
for(int i=1;i<=n;i++){
insert(a[i]);
left_s[i]=i-getsum(a[i]);
}
//求右边比其小的数个数
memset(c,0,sizeof(c));
for(int i=n;i>0;i--){
insert(a[i]);
right=getsum(a[i]-1);
ll k=right+left_s[i];//因这里k之前声明成int型,偏小了
ans=ans+(k+1)*k/2;
}
cout<<ans<<endl;
getchar();
getchar();
return 0;
}