我如何计算模数为m的主电力塔

时间:2017-04-24 15:45:04

标签: algorithm math primes number-theory modular-arithmetic

这是问题 - 我给了一个素数P和一个数K.我需要计算P ^ P ^ P ... k次模数为m。

这里P是素数。

(P ^ (P ^ (P ^ P .... k times))) % m

几个例子

对于P = 2,K = 3,m = 3

2 ^ 2 ^ 2 % 3 = 1

对于P = 5,K = 3,m = 3

5 ^ 5 ^ 5 % 3 = 2

我可以做一个蛮力,但问题是数字会变得非常大。

这是约束

2 <= p < 10 ^ 8
1 <= k < 10 ^ 8 
1 <= m <= 10 ^ 8

1 个答案:

答案 0 :(得分:3)

假设取幂是左关联的,意味着你必须计算:

[(p^p)^p]^p ... k times

注意:如果这是一个错误的假设,那么您的问题与this question重复。事实上,由于p是最优秀的,因此更容易。

然后这等于:

p^(p*p*p*... k times)

等于:

p^(p^k)

使用exponentiation by squaring这可以在O(log p^k) = O(k log p)

中使用

但是,对于您声明的p, k < 10^8限制,这仍然太多了。

为了让效果更好,您可以this answer使用Douglas Zare中的一些信息:

  

你可以说a ^ k mod m = a ^(k mod phi(m))mod m。然而,当a和m不是相对素数时,这并不总是正确的

幸运的是,a = p在我们的案例中,而p是素数,所以保持不变。

所以你的问题减少到了计算:

p^(p^k mod phi(m)) mod m

通过平方需要两次取幂,这很容易实现。

请参阅how to compute the totient function efficiently

int phi(int n)
{    
    int result = n;   // Initialize result as n

    // Consider all prime factors of n and subtract their
    // multiples from result
    for (int p=2; p*p<=n; ++p)
    {
        // Check if p is a prime factor.
        if (n % p == 0)
        {
            // If yes, then update n and result 
            while (n % p == 0)
                n /= p;
            result -= result / p;
        }
    }

    // If n has a prime factor greater than sqrt(n)
    // (There can be at-most one such prime factor)
    if (n > 1)
        result -= result / n;
    return result;
}