题目:传送门。
分析:求序列的逆序数。用树状数组和归并排序都可以做,因为a[i]可能有999,999,999这么大,所以先对数据进行离散。
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
struct DATA{
int val,posi;
};
const int MAXN=5e5+5;
int n,a[MAXN],bit[MAXN];
DATA data[MAXN];
bool comp(DATA& a,DATA& b){
return a.val<b.val;
}
void add(int i){
while(i<=n){
bit[i]+=1;
i+=i&-i;
}
}
int sum(int i){
int _sum=0;
while(i>0){
_sum+=bit[i];
i-=i&-i;
}
return _sum;
}
void solve(){
__int64 ans=0;
for(int i=1;i<=n;++i) bit[i]=0;
for(int i=1;i<=n;++i){
add(a[i]);
ans+=i-sum(a[i]);
}
cout<<ans<<endl;
}
int main(){
ios::sync_with_stdio(false);
while(cin>>n,n){
for(int i=1;i<=n;++i){
cin>>data[i].val;
data[i].posi=i;
}
sort(data+1,data+1+n,comp);
for(int i=1;i<=n;++i){
a[data[i].posi]=i;
}
solve();
}
return 0;
}
#include <iostream>
#include <cstdio>
using namespace std;
const int MAXN=5e5+5;
int A[MAXN],T[MAXN];
__int64 ans;
void Merg_Sort(int l,int r){
if(l>=r-1) return ;
int mid=l+(r-l)/2;
Merg_Sort(l,mid);
Merg_Sort(mid,r);
int p=l,q=mid,i=l;
while(p<mid||q<r){
if(q>=r||(p<mid&&A[p]<=A[q])) T[i++]=A[p++];
else{
if(p<mid) ans+=mid-p;
T[i++]=A[q++];
}
}
for(int i=l;i<r;++i){
A[i]=T[i];
}
}
int main(){
ios::sync_with_stdio(false);
int n;
while(cin>>n,n){
ans=0;
for(int i=0;i<n;++i){
cin>>A[i];
}
Merg_Sort(0,n);
cout<<ans<<endl;
}
return 0;
}