快速幂(所有可能溢出的地方都要mod)
递归写法
几点注意事项:1、temp在里面要先算出来一半再temp*temp,不然两次进循环复杂度增加
2、%m不要忘了写
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<stdio.h> #include<iostream> #include<string.h> using namespace std; int binaryPow(int a,int b,int m) { int temp; if(a==0) return 0; if(m==1) return 0; if(b==0) return 1; if(b==1) return a%m; a=a%m; if(b&1) { return a*binaryPow(a,b-1,m)%m; } else temp=binaryPow(a,b/2,m)%m; return temp*temp%m; } int main() { int a,b,m; scanf("%d%d%d",&a,&b,&m); printf("%d^%d mod %d=%d",a,b,m,binaryPow(a,b,m)); return 0; }
迭代写法
注意a*a的位置也要modm 不然可能会溢出导致结果错误。
迭代中 eg:b=10 对应的二进制1001 这时候就是a^8*a^2
里面的a一直随着b走向高位每次都是a*a(注意是a*a不是a平方,因为二进制位数符号是16 8 4 2 这种的)
还有就是第一次是要先动ans再动a*a,否则会错位
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<stdio.h> #include<iostream> #include<string.h> using namespace std; int binaryPow(int a,int b,int m) { if(m==1) return 0; int ans=1; a=a%m; while(b>0) { if(b%2==1) { ans=ans*a%m; } a=a*a%m; b=b/2; } return ans; } int main() { int a,b,m; scanf("%d%d%d",&a,&b,&m); printf("%d^%d mod %d=%d",a,b,m,binaryPow(a,b,m)); return 0; }
实际操作差别不大,我觉得递归更方便一点
int的范围是-2^31~2^31-1
时间才能证明一切,选好了就尽力去做吧!