快速取模
typedef long long LL;
LL quick(LL a,LL b,LL m) //a^b%m 快速取模 使得复杂度从0(b)
{ // 降低为0(log2(b))
LL ans=1;
while(b)
{
if(b&1) ans=ans*a%m;
b>>=1;
a=a*a%m;
}
return ans;
}
LL multi(LL a,LL b,LL m) // a*b%m 快速取模
{
LL ans=0;
while(b)
{
if(b&1) ans=(ans+a)%m;
b>>=1;
a=(a+a)%m;
}
return ans;
}
例题:
Given A,B,C, You should quickly calculate the result of A^B mod C. (1<=A,B,C<2^63).
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long LL;
LL multi(LL a ,LL b,LL m)
{
a%=m;
LL ans=0;
while(b)
{
if(b&1)
//ans=(ans+a)%m;
{
ans+=a;
if(ans>=m)
ans-=m;
}
b>>=1;
//a=(a+a)%m; 使用加减及位运算速度比乘除及模运算快
a<<=1;
if(a>=m)
a-=m;
}
return ans;
}
LL quick(LL a,LL b,LL m)
{
LL ans=1;
a=a%m;
while(b)
{
if(b&1)
//ans=ans*a%m;
ans=multi(ans,a,m);
b>>=1;
a=multi(a,a,m);
}
return ans;
}
int main()
{
LL a,b,c;
while(scanf("%I64d%I64d%I64d",&a,&b,&c)!=EOF) //有些oj不认识%lld,可以使用%I64d
{
printf("%I64d\n",quick(a,b,c));
}
return 0;
}