在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。
如2 4 3 1中,2 1,4 3,4 1,3 1是逆序,逆序数是4。给出一个整数序列,求该序列的逆序数。
Input
第1行:N,N为序列的长度(n <= 50000) 第2 - N + 1行:序列中的元素(0 <= A[i] <= 10^9)
Output
输出逆序数
Input示例
4 2 4 3 1
Output示例
4
排序方法中的一种归并排序,利用分治的思想,同样减少了交换次数,提高效率。
同时可以求出逆序数。
#include<stack>
#include<queue>
#include<math.h>
#include<vector>
#include<string>
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<map>
#define maxn 50005
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define mod 1000000007
#define inf 0x3f3f3f
using namespace std;
int a[maxn];
ll ans=0;
void merge_sort(int l,int mid,int r){
int k=0;int temp[maxn];
int i=l,j=mid+1,m=mid,n=r,f=0;
while(i<=m&&j<=n){
if(a[i]<=a[j])temp[k++]=a[i++];
else{
temp[k++]=a[j++];ans+=(m-i+1);}
}
while(i<=m){
temp[k++]=a[i++];
}
while(j<=n){
temp[k++]=a[j++];
}
for(int p=0;p<k;p++){
a[l+p]=temp[p];
}
}
void Merge(int l,int r){
if(l<r){
int mid=(l+r)/2;
Merge(l,mid);
Merge(mid+1,r);
merge_sort(l,mid,r);
}
}
int main(){
int x;
while(cin>>x){
for(int i=0;i<x;i++){
cin>>a[i];
}
ans=0;
Merge(0,x-1);
cout<<ans<<endl;
}
}