你的实现是一个简单的实现,它需要 O(n^2) 的时间,但是要让解决方案被接受,你必须像在合并排序中那样使用分而治之,与更简单的排序相比,它只需要 O(NLogN) 时间冒泡排序等算法。
为此,您只需在其中添加 2-3 行代码即可稍微更改 Mergesort 实现。为了更好地理解这一点,请通过计算数组中的反转问题。(http://www.geeksforgeeks.org/counting-inversions/)然后你会意识到你只需要考虑本质上与反转相反的对并添加所有较小的对所有此类对的元素。例如 - 在数组 1,4,2,5 中考虑 4,2 是反转,但我们必须考虑像 2,5 和 1,2 这样的对来获得解决方案。在每一对这样的对中,继续添加左边的号码。(仔细想想它是如何完成我们的工作的!!)
供您参考,请彻底阅读此合并排序代码,其中我有一些小的更改以获得正确的可接受的解决方案。(sum 变量存储结果值)
#include <stdio.h>
#include <stdlib.h>
long long int sum;
void merge(long long int c[],long long int arr[],long long int start,long long int middle,long long int end)
{
long long int i=0,j=start,k=middle;
while((j<middle)&&(k<end))
{
if(arr[j]<arr[k])
{
sum=sum+((end-k)*arr[j]);
c[i]=arr[j];
i++;j++;
}
else
{
c[i]=arr[k];
i++;k++;
}
}
while(j<middle)
{
c[i]=arr[j];
i++;
j++;
}
while(k<end)
{
c[i]=arr[k];
i++;
k++;
}
}
void msort(long long int arr[],long long int start,long long int end)
{
long long int middle=(start+end)/2;
if((end-start)==1)
{ return ;
}
msort(arr,start,middle);
msort(arr,middle,end);
long long int *c;
c=(long long int*)malloc(sizeof(long long int)*(end-start));
merge(c,arr,start,middle,end);
long long int i,j=0;
for(i=start;i<end;i++)
{
arr[i]=c[j];
j++;
}
}
void swap (long long int x[],long long int m,long long int n)
{
long long int t= x[m];
x[m]=x[n];
x[n]=t;
}
int main()
{
int t,i;
long long int n,*arr,j;
scanf("%d",&t);
for(i=0;i<t;i++)
{
scanf("%lld",&n);
arr = ( long long int * ) malloc ( sizeof(long long int) * n + 10);
for(j=0;j<n;j++)
{
scanf("%lld",&arr[j]);
}
sum=0;
msort(arr,0,n);
// for(j=0;j<n;j++)
// printf("%lld ",arr[j]);
printf("%lld\n",sum);
}
return 0;
}