分析:
可以采用将n个数字序列分成两部分,对每部分都进行排序并统计出每一部分的逆序数,然后我们将这两个子部分进行合并排序,并且同时统计出逆序数,最终的逆序数就等于这三步逆序数的和。在进行合并的时候设置两个指针i,j,分别指向两个子序列的首元素,并可以向后移动。指针移动的规则是将所指两个元素进行比较,数值小的那个指针向后移动,并且如果前子序列数大,就将逆序数加n/2-i。如此递归求解,能得到最终结果。
代码实现(C/C++):
#include<iostream>
#include<fstream>
using namespace std;
#define N 100000
int data[N];
long merge_count(int A[],int l,int r)
{
int p=0;
int k=0;
int m=(l+r)/2;
int pl=l;
int pr=m+1;
int count=0;
int b=m+1;
while(pl<=m&&pr<=r)
{
if(A[pl]<=A[pr])
data[p++]=A[pl++];
else
data[p++]=A[pr++];
}
if(pl>m)
while(pr<=r)
data[p++]=A[pr++];
if(pr>m)
while(pl<=m)
data[p++]=A[pl++];
for(p=l;p<=r;p++)
A[p]=data[k++];
for(int a=l;a<=m;a++)
{
while(A[a]>=A[b]&&b<=r) b++;
count+=b-m-1;
}
return count;
}
long sort_count(int A[],int l,int r)
{
if(l==r) return 0;
int m=(l+r)/2;
long rcl=sort_count(A,l,m);
long rcr=sort_count(A,m+1,r);
long rclr=merge_count(A,l,r);
return (rcl+rcr+rclr);
}
void main()
{
int array[N];
ifstream fin;
fin.open(“Q5.txt”);
for(int i=0;i<N;i++)
fin>>array[i];
fin.close();
cout<<sort_count(array,0,N-1)<<endl;
}