问题描述
3 2 5 1 4 中,(3, 2), (3, 1), (2, 1), (5, 1), (5, 4)是其5个逆序。
输入
第一行是一个整数n,表示该排列有n个数(n <= 100000)。
第二行是n个不同的正整数,之间以空格隔开,表示该排列。
输出
输出该排列的逆序数。
样例输入
5
3 2 5 1 4
样例输出
5
限时一秒
思路:利用二分归并排序算法(分治)
答案来自网络:平台得分66.6666,三组测试数据,最后一组反馈超时
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
int n,a[100009],tmp[100009];
long sum;
void Merge_sort(int,int);
void Merge_nx(int,int,int);
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
Merge_sort(1,n);
printf("%ld",sum);//输出逆序总数
return 0;
}
void Merge_sort(int l,int r)
{
if(l<r)//要有判断
{
int mid=(l+r)>>1;//**
Merge_sort(1,mid);//归并左边
Merge_sort(mid+1,r);//归并右边
Merge_nx(l,mid,r);//归并排序
}
}
void Merge_nx(int l,int m,int r)
{
int z=l,y=m+1;
int num=l;// num=l***
while(z<=m&&y<=r)
{
if(a[z]<=a[y])
{
tmp[num++]=a[z++];
}
else
{
tmp[num++]=a[y++];
sum+=(m-z+1);//逆序总数
}
}
while(z<=m){tmp[num++]=a[z++];}//将剩下的直接放入
while(y<=r){tmp[num++]=a[y++];}
for(int i=l;i<=r;i++)//l---r
a[i]=tmp[i];//将排好的数返回
}