改进gcd的方法

时间:2015-01-04 09:17:30

标签: algorithm

问题:

您将获得一个大小为N的整数数组A.您将获得Q查询,其中每个查询由两个整数L,R表示。在从范围中排除部分后,必须找到数组的gcd(最大公约数) L到R包含N ≤ 10^6, 1 ≤ Q ≤ N,

我的方法: 计算前缀GCD然后后缀GCD并返回答案。 代码:

public static int gcd(int a , int b){


    if(b==0) return a;

    return gcd(b,a%b);
}

for(int i=1;i<=n;i++){

        pre[i] = gcd(a[i],pre[i-1]);
    }
    suff[n]=a[n];
    for(int i=n-1;i>0;i--){

        suff[i] = gcd(a[i],suff[i+1]);

    }
    for(int i=0;i<t;i++){
        int l = in.nextInt();
        int r =in.nextInt();
        if(r!=n)
        System.out.println(gcd(pre[l-1],suff[r+1]));
        else
            System.out.println(pre[l-1]);
    }

问题:这种方法让我的时间限制超出错误我可以改进我的解决方案吗?请帮忙

2 个答案:

答案 0 :(得分:0)

这看起来大致对我来说,但它确实对一些查询做了很多工作。假设您给出的Q查询都将L设置为0;在这种情况下,您不需要任何前缀计算。或者假设只有一个查询:你计算的前缀和后缀多于你需要的。

我首先循环查询Q查询并找到R的最小值和L的最大值。这样您就可以计算回答这些查询所需的前缀和后缀。< / p>

加速的另一个潜在区域在于gcd功能,您尚未向我们展示。

顺便说一句,当L为0时,您的代码当前不起作用。它会尝试检查pre[-1]

编辑:gcd看起来不错。

答案 1 :(得分:0)

让我们创建两个数组arr和大小为Nr的brr。其中arr [i]将输入数组中所有数字的gcd存储到索引i(包括i)和brr [i]将存储所有gcd索引i之后的输入数组中的数字包括i。

示例 - &GT; arr [3] = gcd(A [0],A [1],A [2],A [3])同样brr将从相反方向初始化 现在假设查询是3,5你可以简单地输出gcd(arr [3],brr [5])