优化我的乘法模算法

时间:2013-08-07 20:36:35

标签: c algorithm optimization multiplication

我有一个问题来自互联网,我有一个N个整数数组,并且必须在给定阵列的左(L)和右段(R)的情况下执行段乘法T次并返回一些给定模数的答案模(M)。

约束

N,T< = 100000

1·; = L< = R< = N

M&LT = 10 ^ 9

和整数< = 100

实施例 -

输入

5(N) 2 5 8 9 4 4(T) 1 2 3 2 3 4 1 1 1 1 5 100000

输出

1 0 0 2880

所以我已经解决了这个问题,但它有点慢,我需要提示来优化我的程序。

#include "stdio.h"

int main(void)
{
        int t;
        scanf("%d",&t);

        int Array[t+1];


    for (int i = 1; i <=t; i++)
    {
        scanf("%d",&Array[i]);
    }

    int N;
    scanf("%d",&N);


    for (int i = 0; i <N ; i++)
    {

        long long a,b,c;
        scanf("%lld%lld%lld",&a,&b,&c);
        long long Product = 1;
        if (c==1)
        {
            Product = 0;

        }
        else
        {

            for (int j = a; j <=b ; j++)
            {

                Product *= Array[j];

                if (Product>=10000000000000000)
                {
                    Product%=c;
                }
            }

        }

        Product%=c;


        printf("%lld\n",Product );

    }

    return 0;
}

1 个答案:

答案 0 :(得分:2)

HINTS

你可以为每个小于100的素数p计算一个数组A_p [i],它指出p除了你的数组第i个条目的次数。

然后你可以计算一个二级数​​组B_p [j],它是i的直到和包括j的A_p [i]的累积和。 (这可以通过递归B_p [i] = B_p [i-1] + A_p [i]在O(n)中完成。)

此辅助数组允许您计算任何范围内每个素数的总功率。例如,如果您想知道素数5在数组条目10到100中出现的次数,您可以计算B_5 [100] -B_5 [10-1]。

因此,对于每个查询,您可以通过将每个素数提高到相应的幂并将结果乘以模M来计算最终答案。请注意,有一种称为exponentiation by squaring的技术可以使计算有效。

如果0是可能的整数,则将0添加到计算中考虑的素数列表中。

FOR INTEREST

请注意,这种使用累积和的方法在许多情况下非常有用。例如,Viola-Jones method for face recognition在2维中使用此技术的一种版本,以便能够有效地计算2d滤镜。