Math 如何计算a^b^c mod p?

Math 如何计算a^b^c mod p?,math,modulo,exponentiation,mod,Math,Modulo,Exponentiation,Mod,我试图计算一些正整数a,b,c,p的a^b^c mod p。一种可能的(也是显而易见的)方法是使用快速模幂运算,它将在O(log(b^c))=clog(b)中运行。虽然我不介意这里的效率,但这种方法的明显缺点是,您需要一个显式的b^c二进制表示,它本身已经是指数形式了 因此,我的问题是,如果我不能将b^c表示为二进制表示,是否有一种方法可以从a、b和c的二进制表示中计算a^b^cmod p (a^b^c) mod p = (((a^b) mod p)^c) mod p 所以你可以 modpow

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

因此,我的问题是,如果我不能将
b^c
表示为二进制表示,是否有一种方法可以从
a、b和c的二进制表示中计算
a^b^c
mod p

(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;
进入

[示例]

(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
解决问题后,请检查此页。 上述答案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;
}
#包括
#定义ar阵列
#定义int long long
使用名称空间std;
常数int mxN=2e5+2,mxM=1003,M=1e9+7;
整数pM(整数n,整数p,整数M)
{
int res=1;
while(p)
{
如果(p&1)
res=res*n%M;
n=n*n%M;
p> >=1;
}
返回res;
}
签名main()
{
int t;
cin>>t;
而(t--)
{
INTA、b、c;
cin>>a>>b>>c;

cout“不能将b^c表示为二进制表示”-您能对此进行扩展吗please@JesseBarnett从编程的角度来看,例如B=2和C=200,这个数字不能被“存储”为二进制表示形式,例如C++的本机数据类型。mod p,而不是a^b^c mod p。这里,a乘以b^c次,而不是a^b乘以c次如果a和p不是共素数,那么你仍然需要使用欧拉的toticent函数。只需计算a^(b^c)mod每个素数幂,并使用中国剩余定理(CRT)来计算答案。或者,更简单地说,如果d=gcd(a,p),然后计算a^x mod(p/d)其中x=(b^c)modñ(p/d)并使用CRT获得答案。计算出的a^(bc)mod p可能是重复的,而不是a^b^c。在这里,a被乘以自身b^c倍!不用担心,谢谢你的回答,我有点困惑。所以这在log(b)log(c)正确吗?@AspiringMat对于正常
int
变量,复杂性是
O(log(b)+log(c))
如果我们假设两个指数都受到
n
的限制,那么复杂度是
O(log(n))
。对于
bigint
操作数,但是操作
+,-,*,/
不再是
O(1)
,因此在这种情况下复杂度要差得多。这个答案是不正确的。(a^b^c)mod p不等于((a^b)mod p)^c)国防部pI同意这并不完全清楚,这就是为什么我没有投反对票。我只是从他的讨论中猜测他指的是a^(b^c)。
#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;
}