逆序数指数组中前面的数大于后面的数的对数;a[i]>a[j]并且i<j;
将数组分为两组L(左)数组和(右)R数组;
将L数组与R数组分别从小到大排序;
在用R数组与左数组逐个比较,假如右数组的数比左数组的第一个数小,则cnt加上左数组的大小,右数组的数比左数组的第一个数大,比左数组的第二个数小则cnt加上左数组的数量减1;同理以次进行;
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
#define MAX 55000
using namespace std;
const int mod=1e9+7;
int a[MAX];
int L[MAX],R[MAX];
ll mersort(int a[ ],int n,int left,int mid,int right )
{
int i,j,k;
ll cnt=0;
int n1=mid-left;
int n2=right-mid;
for(i=0; i<n1; i++)
L[i]=a[left+i];
for(i=0; i<n2; i++)
R[i]=a[mid+i];
L[n1]=mod,R[n2]=mod;
i=j=0;
for(k=left; k<right; k++)
{
if(L[i]<=R[j])
{
a[k]=L[i++];//将数组从小到大排序
}
else
{
a[k]=R[j++];//将数组从小到大排序
cnt+=n1-i;
}
}
return cnt;
}
ll mergasort(int a[ ],int n,int left,int right)
{
int mid;
ll v1,v2,v3;
if(left+1<right)//最少有个两数才能比较;
{
mid=(left+right)/2;
v1=mergasort(a,n,left,mid);
v2=mergasort(a,n,mid,right);
v3=mersort(a,n,left,mid,right);
return v1+v2+v3;
}
else
return 0;
}
int main( )
{
ll n;
cin>>n;
for(int i=0; i<n; i++)
{
cin>>a[i];
}
ll ans=mergasort(a,n,0,n);
cout<<ans<<endl;
return 0;
}
归并排序就是应用上述中的排序:
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
#define MAX 55000
using namespace std;
ll n;
const int mod=1e9+7;
int a[MAX];
int L[MAX],R[MAX];
void mersort(int a[ ],int n,int left,int mid,int right )
{
int i,j,k;
int n1=mid-left;
int n2=right-mid;
for(i=0;i<n1;i++) L[i]=a[left+i];
for(i=0;i<n2;i++) R[i]=a[mid+i];
L[n1]=mod,R[n2]=mod;
i=j=0;
for(k=left;k<right;k++)
{
if(L[i]<=R[j])
{
a[k]=L[i++];
}
else
{
a[k]=R[j++];
}
}
}
void mergasort(int a[ ],int n,int left,int right)
{
int mid;
ll v1,v2,v3;
if(left+1<right)
{
mid=(left+right)/2;
mergasort(a,n,left,mid);
mergasort(a,n,mid,right);
mersort(a,n,left,mid,right);
}
}
int main( )
{
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
}
mergasort(a,n,0,n);
for(int i=0;i<n;i++)
{
if(i)
{
cout<<" ";
}
cout<<a[i];
}
cout<<endl;
return 0;
}