竞争性编程:“时间超出错误”

时间:2018-11-22 13:55:09

标签: c gcc optimization

问题描述:

  

任务A.减去量

     

您有一个数组 a 长度 n 。有m个查询   ( l i ,r i ),对于每个   查找数字总和子数组   [ l i ,r i ]

     

输入数据格式:

     

第一行包含两个整数 n m(1⩽n,m⩽   10 5 -数字和查询数。第二   该行包含 n 个整数 a 1 ,a 2 。 。 。 ,   a n (1⩽a i ⩽10 9 -   数组。以下m行中的每行包含两个整数    l i r i (1 l i r r i n) -查询。

     

输出数据格式:

     

对于每个请求,请在一行中单独回答。

我的解决方案:

#include <stdio.h>

int main(void) {
    long n = 0;
    long m = 0;

    long l = 0;
    long r = 0;

    register long t = 0; // temporary variable, that contains intermediate results

    scanf("%ld%ld", &n, &m);

    long  a[n];
    long  tr[m]; // array, that contains results

    for (register long i = 0; i < n; i++)
        scanf("%ld", &a[i]);

    for (register long i = 0; i < m; i++) {
        scanf("%ld%ld", &l, &r);

        l--;
        r--;

        t = 0;
        if (l != r) {
            for (register long j = l; j <= r; j++)
                t += *(a + j);
        } else t = *(a + l);

        tr[i] = t; 
    }
    for (register long i = 0; i < m; i++)
        printf("%ld\n", tr[i]);


    return 0;
}

我的解决方案仅通过了11个中的6个测试。其他5个始终返回

  

时间超出错误

我真的是竞争编程的新手。 我应该如何优化代码以使big-O复杂度小于O(n 2 )? 任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

计算数组的累加和并将其存储在另一个数组中,也就是说, accumulated[i] =直到第i个索引的数组数的总和。可以用O(n)来计算。

然后进行查询,答案将为accumulated[r] - accumulated[l]。这是O(1)

答案 1 :(得分:0)

这个问题可以用 O(n) 的时间复杂度和 O(n) 的空间复杂度来解决。

您可以使用前缀和方法来降低复杂度。假设一个长度为 4 的数组包含元素 a0、a1、a2、a3,创建一个单独的数组,其中包含索引 i 的 i 个元素的总和。

原始数组arr[]: a0, a1, a2, a3
前缀和数组 p[]: a0, a0+a1, a0+a1+a2, a0+a1+a2+a3

对于'a1和a2'的和:a1+a2 = p[2] - p[0]

对于'a1和a2和a3'的和:a1+a2+a3 = p[3] - p[0]
对于'a2和a3'的和:a2+a3 = p[3] - p[1]

以上几行表示对于从'L到R'的元素之和,我们必须打印p[R] - p[L-1]

注意:对于 L=0,我们必须打印 p[R],因为它是直到 R 的所有元素的总和,而且没有索引为 '-1' 的元素。

创建前缀和数组的代码:

如果我们有一个包含 'long int' 数据类型并命名为 arr、大小为 n 的数组,则:

long p[n];
p[0] = arr[0];
for(long i=1;i<n;i++)
{
    p[i] = p[i-1] + arr[i];
}