我正在尝试解决SPOJ上需要模幂运算的问题。我使用以下C代码
long long modpow(long long a,long long b,long long mod)
{
long long product,pseq;
product=1
pseq=a%mod;
while(b>0)
{
if(b&1)
product=(product*pseq)%mod;
pseq=(pseq*pseq)%mod;
b>>=1
}
return product;
}
问题是,当我想要计算(2^249999999997)%999999999989
时,由于溢出,它会给出答案0
。我怎样才能避免溢出?
答案 0 :(得分:4)
Untestet,但你明白了。只要2*mod
小于最大可表示long long
值且a
,b
和mod
为正值,这就应该有效。
long long modpow(long long a,long long b,long long mod)
{
long long product,pseq;
product=1;
pseq=a%mod;
while(b>0)
{
if(b&1)
product=modmult(product,pseq,mod);
pseq=modmult(pseq,pseq,mod);
b>>=1;
}
return product;
}
long long modmult(long long a,long long b,long long mod)
{
if (a == 0 || b < mod / a)
return (a*b)%mod;
long long sum;
sum = 0;
while(b>0)
{
if(b&1)
sum = (sum + a) % mod;
a = (2*a) % mod;
b>>=1;
}
return sum;
}
答案 1 :(得分:0)
另外一个建议是利用999999999989是素数的事实。 通过使用关系,(a ^ n)= a%n(其中n是素数),你可以简化操作。
答案 2 :(得分:-1)
你可以使用 unsigned long long 而不是 long long ,它可以帮助你玩更高的值,范围是0到18,446,744,073,709,551,615。