我们得到一个数组a[1..N]
。对于数组中的每个元素a[i]
,我们记下所有元素的总和,这些元素较小并出现在当前元素之前。我需要计算数组中每个元素的总和。
约束:
1·; = N&LT = 10 ^ 5
所有元素都在0到10 ^ 6之间。
以下是我的问题的链接:http://www.spoj.com/problems/DCEPC206/。我正在使用下面显示的方法,但我在SPOJ上遇到TIME LIMIT EXCEEDED
错误。我该如何改进我的解决方案?
include
int main()
{
long n,a[100000],i,j,sum;
printf("enter the number of elements");
scanf("%ld",&n);
printf("enter the elements of the array");
for(i=0;i<n;i++)
scanf("%ld",&a[i]);
sum=0;
for(i=1;i<n;i++)
for(j=i-1;j>=0;j--)
if(a[i]>a[j])
sum+=a[j];
printf("\n%ld",sum);
return 0;
}
答案 0 :(得分:0)
你的是一个简单的实现,它需要O(n ^ 2)的时间顺序,但是为了使解决方案被接受,你必须像在Merge Sort中那样使用Divide and Conquer,它只需要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;
}