【问题标题】:Finding pow(a^b)modN for a range of a's查找 a 范围内的 pow(a^b)modN
【发布时间】:2013-08-04 09:17:18
【问题描述】:

对于给定的bN 以及a 的范围,比如(0...n)

我需要找到ans(0...n-1) 哪里,

ans[i] = 没有a's,其中pow(a, b)modN == i

我在这里搜索的是pow(a,b)modN 中可能重复的a 范围,以减少计算时间。

例子:-

如果b = 2N = 3n = 5

for a in (0...4):
    A[pow(a,b)modN]++;

原来如此

pow(0,2)mod3 = 0
pow(1,2)mod3 = 1
pow(2,2)mod3 = 1
pow(3,2)mod3 = 0
pow(4,2)mod3 = 1

所以最终的结果是:

ans[0] = 2 // no of times we have found 0 as answer .

ans[1] = 3

...

【问题讨论】:

  • 这个问题来自哪个编码竞赛?
  • 请举个例子让我们理解问题。
  • @UchiaItachi 更新了..
  • 不确定是否理解您的示例。你写了 pow(3,2)mod3 = 2。但是 pow(3,2) = 9。而 9mod3 = 0。
  • @GerardWalace 哎呀.. 更新了。

标签: c algorithm math modulo


【解决方案1】:

您的算法的复杂度为 O(n)。 这意味着当 n 变大时需要很长时间。

您可以使用 O(N) 算法得到相同的结果。 由于 N

首先,两个数学事实:

pow(a,b) modulo N == pow (a modulo N,b) modulo N

if (i < n modulo N)
   ans[i] = (n div N) + 1
else if (i < N)
   ans[i] = (n div N)
else
   ans[i] = 0

因此,解决问题的方法是使用以下循环填充结果数组:

int nModN = n % N;
int nDivN = n / N;
for (int i = 0; i < N; i++)
{
    if (i < nModN)
        ans[pow(i,b) % N] += nDivN + 1;
    else
        ans[pow(i,b) % N] += nDivN;
}

【讨论】:

  • "Your algorithm has a complexity of O(n)" - 我不确定我是否会将a^b 视为O(1) 操作。
  • 你是对的。但这取决于您的处理器架构。例如,在 x86 上,它应该是一个时间常数操作。没关系,我必须承认我可能过度简化了我的复杂性计算,因为它以相同的方式影响两种算法。感谢您的评论。
【解决方案2】:

您可以只计算素数的pow,并使用pow(a*b,n) == pow(a,n)*pow(b,n)

所以如果pow(2,2) mod 3 == 1pow(3,2) mod 3 == 2,那么pow(6,2) mod 3 == 2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-19
    • 2012-09-18
    • 2017-04-26
    相关资源
    最近更新 更多