这是问题 - 我给了一个素数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
答案 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;
}