如何计算^ b ^ c mod p?

时间:2017-10-26 01:45:35

标签: math modulo exponentiation mod

我正在尝试计算某些正整数a,b,c,p的^ b ^ c mod p。一种可能的(也是显而易见的)方法是使用快速模幂运算,它将在O(log(b^c))=clog(b)中运行。虽然我不介意这里的效率,但这种方法的明显缺点是你需要b^c的显式二进制表示,它本身已经是指数的。

所以对我来说问题是,如果我不能将b^c表示为二进制表示,我是否可以通过a^b^c的二进制表示来计算a,b, and c mod p?

2 个答案:

答案 0 :(得分:0)

(a^b^c) mod p = (((a^b) mod p)^c) mod p

所以你可以做到

modpow(modpow(a,b,p),c,p);

所有操作数结果和子结果都是正常的整数。作为modpow,您可以通过模拟p这样的方式来使用权力:

要注意那些利用特定选定p的属性进行了一些优化,因此您需要更改

之类的行
if (DWORD(d)>=DWORD(p)) d-=p;

d%=p;

<强> [实施例]

(2^3^5) % 6 = 
(8  ^5) % 6 =
  32768 % 6 = 2

(((2^3)%6)^5) % 6 = 
((   8 %6)^5) % 6 = 
(    2    ^5) % 6 =
    32        % 6 = 2

答案 1 :(得分:0)

https://discuss.codechef.com/t/compute-a-b-c-mod-p/1989 在解决 https://cses.fi/problemset/task/1712 后检查此页面。 上面的答案 modpow(modpow(a,b,p),c,p); 看起来很合逻辑, 但它不起作用(您可以通过上面提到的 CSES 问题进行验证)。使用这个公式/方法 modpow(a,modpow(b,c,p-1),p); 。 他们使用费马定理推导出这个 modpow(a,modpow(b,c,p-1),p);。 顺便说一下cpp代码如下:

#include <bits/stdc++.h>
#define ar array
#define int long long
using namespace std;

const int mxN=2e5+2,mxM=1003,M=1e9+7;

int pM(int n,int p,int M)
{
    int res=1;
    while(p)
    {
        if(p&1)
            res=res*n%M;
        n=n*n%M;
        p>>=1;
    }
    return res;
}
signed main()
{
    int t;
    cin>>t;
    while(t--)
    {
         int a,b,c;
        cin>>a>>b>>c;
        cout<<pM(a,pM(b,c,M-1),M)<<"\n";
    }

    return 0;
}