题目链接:
点击打开链接
遍历读入的数组,每读到一个数就说明这个地方的数字个数多了1,然后算一下这时候比它大的却在它之前读的数字有几个加起来就好了。数字有点大hash一下。
#include<iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn = 500005;
int n;
int c[maxn];
struct node{
int num,hashNum,t;
}a[maxn];
bool cmp(node a,node b){
return a.num<b.num;
}
bool cmp1(node a,node b){
return a.t<b.t;
}
int lowbit(int x){
return x&(-x);
}
void add_num(int pos, int num){
for(int i=pos; i<=n; i+=lowbit(i))
c[i]+=num;
}
long long get_sum(int pos){
long long ans = 0;
for(int i=pos; i>=1; i-=lowbit(i)){
ans += c[i];
}
return ans;
}
int main(){
while(scanf("%d",&n)){
if(n==0) break;
memset(c,0,sizeof(c));
for(int i=1; i<=n; i++){
scanf("%d",&a[i].num);
a[i].t = i;
}
sort(a+1,a+n+1,cmp);
for(int i=1; i<=n; i++){
a[i].hashNum = i;
}
sort(a+1,a+n+1,cmp1);
int x;
long long ans = 0;
for(int i=1; i<=n; i++){
x = a[i].hashNum;
add_num(x,1);
ans += (get_sum(n)-get_sum(x));
}
printf("%lld\n",ans);
}
return 0;
}