我想找到(num *(pow(b,p)-1)/ den)%mod。我知道二进制求幂。但是我们不能直接做到这一点。保证分子可被分母整除。这意味着
[num *(pow(b,p)-1)]%den == 0
对mod的约束是1 <= mod <= 10 ^ 9,并且mod可能是素数或复合
对b的约束:1 <= b <= 10
对p的约束:1 <= p <=(10 ^ 18)
限制num:1 <= num <=(10 ^ 9)
对den的约束:1 <= den <=(10 ^ 9)
这里pow(b,p)表示b升为幂p(b ^ p)。保证分子可被分母整除。我该如何使用二进制幂运算
答案 0 :(得分:1)
您的表达式应重写为简化形式。首先让k = num / den,根据您的问题为k整数。
所以您必须计算
(k×(b ^ p-1))mod m =((k mod m)×((b ^ p -1)mod m))mod m
=((k mod m)×((b ^ p mod m)-1 mod m)mod m)mod m
=(((k mod m)×((b ^ p mod m)+ m-1)mod m)mod m(1)
所以真正的问题是计算b ^ p mod m
许多语言(python,java等)在其标准库中已经具有模块化指数。请查阅文档并使用它。否则,这是一个C实现。
unsigned long long modexp(unsigned long long b, unsigned long long e, unsigned long long m) {
if (m==1) return 0;
unsigned long long res=1;
unsigned long long bb = b % m;
while (e) {
if (e & 1)
res = (res*b) % m;
e >>= 1;
bb = (bb*bb) % m;
}
return res;
}
该实现使用long long
来满足您的约束。它依赖于二进制求幂的经典技巧。计算所有b ^ l的值,其中l是2的幂(l = 2 ^ t)并将其存储在var bb中,如果e的对应的t th 位置1,则该值b ^ l被集成到结果中。通过检查e的连续奇偶校验来完成位测试,同时在每一步向右移动e。
最后,(a×b)mod m =((a mod m)×(b mod m))mod m的事实用于避免对非常大的数进行计算。我们总是有res 然后,您只需应用(1)即可获得最终结果。 根据注释中给出的精度进行编辑 我们可以仅以2 * m的模数应用前面的方法,然后将结果(将是偶数)除以2。
要计算n =(3 ^ p-1)/ 2 mod m,可以指出
(3 ^ p-1)/ 2 = x * m + n(因为3 ^ p-1是偶数,x是整数,0≤n
所以2n =(3 ^ p-1)mod 2m