Prepared for New Acmer
蒙哥马利幂模思想:
在幂模运算中,通常是用幂模运算转换为乘模运算。有以下两个公式:
1)a*b%n=(a%n)*(b%n)%n
2)(a+b)%n=(a%n+b%n)%n
当我们计算D=C^15%N时,有:
C1=C*C%N=C^2%N
C2=C1*C%N=C^3%N
C3=C2*C2%N=C^6%N
C4=C3*C%N=C^7%N
C5=C4*C4%N=C^14%N
C6=C5*C%N=C^15%N
所以,幂模运算可以转化为乘模运算。继续看,我们会发现,要求D=C^E%N,要知道E何时能整除2,并不需要反复进行减一或者除二的操作,只需要验证E的二进制个位是0还是1就行了。
本题代码:#include <cstdio>
__int64 fun(__int64 A,__int64 B,__int64 C)
{
__int64 k = 1;
A%=C;
while(B>=1)
{
if((B&1)!=0)
k = (k*A)%C;
B>>= 1;
A = A*A%C;
}
return k;
}
int main(int argc, char *argv[])
{
int n;
scanf("%d",&n);
__int64 A,B,C;
while(n--)
{
scanf("%I64d%I64d%I64d",&A,&B,&C);
printf("%I64d\n",fun(A,B,C));
}
return 0;
}
普通代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <iomanip>
using namespace std;
int main(int argc, char *argv[])
{
int n;
scanf("%d",&n);
int A,B,C;
while(n--)
{
scanf("%d%d%d",&A,&B,&C);
__int64 ans = 1;
for(int i = 1; i <= B; i++)
{
ans*=A;
ans%=C; //注意要求余,不然很容易数据溢出;
}
printf("%I64d\n",ans);
}
return 0;
}