一、题目背景
已知底数a,指数b和模数mo,求ans = ab % mo。
二、朴素算法
就是暴力啦~~
1 void power(int a,int b,int mo){ 2 long long ans=1; 3 for(int i=1;i<=b;i++){ 4 ans*=a; 5 ans%=mo; 6 } 7 }
三、快速幂取模
先讨论无需取模的
当b为偶数时:ab=a(b/2)*2=(a2)b/2
当b为奇数时:ab=a*ab-1=a*(a2)(b-1)/2
如 28=(22)4 27=2*(22)3
所以,我们可以如此迭代下去
210=(22)5=(22)*[(22)2]2
① ② ③
指数为10 是一个偶数,则底数2平方,指数变为一半 [ ①→② ]
指数为5 是一个奇数,则先将底数提出作为系数(22),此时指数为4 是一个偶数,则底数22再平方,指数再变为一半 [ ②→③ ]
归纳总结得到:
当指数大于1时,若为 偶数 则将指数除以2,底数平方
若为 奇数 则先提出一个为底数的系数(可直接把该系数乘进ans中),所以指数减1,然后再按照 偶数 的办法做
不断迭代下去,当指数为1时,则直接得出答案
最后只要将每次相乘时取模即可,时间复杂度O(log2b)
1 long long FastPower(int a,int b,int mo){ 2 long long ans=1; a%=mo; 3 while(b){ 4 if(b & 1) ans=(ans*a)%mo;// b 此时是奇数 5 b >> 1;// 相当于是 b /= 2 ; 6 a=(a * a) % mo; 7 } 8 return ans; 9 }