快速幂算法原理
先不对其取模 只快速求解 a的b次方
//快速求出a的b次方
//关键点有二 1.二进制拆分 2.平方倍增
//二进制拆分 将指数转化为二进制数
//例如 5的13次方 13=8+4+1 即1101
//每次拿出二进制码的最右边一位和1做&运算判断是否为1
//如果最右位为1则乘上当前的a
//a从1次倍增到2次4次8次.....无论当前最右位为是否为1
//a都要进行倍增
/*例如 5的13次 1101
初始 a=5;res=1;
最后一位是1,res=res*a; res=5的1次;
a倍增:a=a*a;即a=5的2次
现在右移一位 二进制码剩下110
当前最右为0 不对res操作,a继续倍增为5的四次
二进制码剩下11 当前最右是1 ,res=res*a; (res=5的一次乘5的四次)
a倍增为5的八次 ; 二进制码剩下1 ,res=res*a;
res=5的1次*5的四次*5的八次 ;结果正好是5的13次;
*/
int quick_pow(int a,int b){
int res=1;
while(b){
//while 当b不为0
if(b&1){
//判断最右位是否位1
res=res*a;
}
a=a*a;//倍增
b>>=1;//b的二进码右移1位
}
return res;
}
下面是结合取模运算
题目链接 P1226 【模板】快速幂 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long LL;
LL quick_pow(int a,int b,int c){
LL res=1;
int p=c;
while(b){
if(b&1){
res=res*a%p;
//满足当前最右位是1 直接 对res处理
}
a=a*(LL)a%p;
//平方倍增 取模运算符合结合率 可以预处理
b>>= 1;
//右移一位
}
return res;
}
int main(){
int a,b,c;
cin>>a>>b>>c;
printf("%d^%d mod %d=%d",a,b,c,quick_pow(a,b,c));
return 0;
}