快速幂的实现
洛谷P1226
题目描述
输入b,p,k的值,求b^p mod k的值。其中b,p,k*k为长整型数。
输入格式
三个整数b,p,k.
输出格式
输出“b^p mod k=s”
s为运算结果
输入输出样例
输入
2 10 9
输出
2^10 mod 9=7
一道位运算入门经典题,几乎所有讲算法的书籍都有所提及,此处就依照李煜东《算法竞赛————进阶指南》书中指导进行介绍。
考虑如下:
对于正整数b,一定可以唯一表示为若干指数不重复的2的次幂的和。
因此,不妨设b在二进制下有k位,其中第i(0<=i<k)位的数字是ci(ci=0或1),那么有:
b=ck-1*2k-1+ck-2*2k-2+…+c0*20
则必有:
ab=a^(ck-1*2k-1)*a^(ck-2*2k-2)*…*a^(c0*20)
(请参考书中式子,避免误解)
k=[log2(b+1)](向上取整),故上式乘积项不多于[log2(b+1)]
所以仅需求出上式的每一项mod p的值
通过a^2i=(a^(2i-1))2每一次不断改变a的值使其变为两倍,及b>>1向右不断移位,并判断b的最末尾是否是1,达到快速取模运算的效果
实际上,该算法时间复杂度应为O(log2n)。

#include<iostream> #include<cstdio> using namespace std; int power(int a,int b,int p){ int ans=1%p; while(b>0){ if(b&1)ans=(long long)ans*a%p; //b&1可以取出b在二进制下最低位 b>>=1;//移位,比b/2快 a=(long long)a*a%p;//改变数值 } return ans; } int main(){ int a,b,p; scanf("%d%d%d",&a,&b,&p); printf("%d^%d mod %d=%d\n",a,b,p,power(a,b,p)); return 0; }