IDEA
1.使用树状数组求逆序数的问题,参考 http://wenku.baidu.com/view/8251fc0516fc700abb68fc76.html?re=view 点击打开链接
2.以中间数为基准,算出左边比其大的数个数,右边比其小的数个数,二者相乘得出结果
3.结果用long long表示
CODE
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
#include<fstream>
using namespace std;
#define MAX 100005
int n;
int a[MAX],c[MAX]={0};
long long l[MAX],r[MAX];
int lowbit(int x){
return x&-x;
}
void add(int x){
while(x<=n){
c[x]++;
x+=lowbit(x);
}
}
int sum(int x){
int s=0;
while(x>0){
s+=c[x];
x-=lowbit(x);
}
return s;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
#endif
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
add(a[i]);
l[i]=i-sum(a[i]);//i为当前已经插入数的个数,sum(a[i])为比a[i]小的数的个数,i-sum(a[i])即为比 比a[i]大的数的个数,即逆序个数
}
for(int i=1;i<=n;i++){
c[i]=0;
}
// for(int i=1;i<=n;i++){
// add(a[i]);
// r[i]=a[i]-sum(a[i]);
// }
for(int i=n;i>=1;i--){
r[i]=sum(a[i]);
add(a[i]);
}
long long count=0;
for(int i=1;i<=n;i++){
count+=l[i]*r[i];
}
cout<<count<<endl;
#ifndef ONLINE_JUDGE
fclose(stdin);
#endif
return 0;
}