快速幂理解
听人介绍这算法很神奇,时间复杂度减很快我就来学学啦。
首先来个题干:求A的B次方的最后三位数。
最基础最普通的想法就是直接循环挨个求然后对1000取模输出,但是有一个问题就是当次方数很大时long long也无法存下最后结果,溢出结果会为0。
进阶版想法就是我昨天刚学的同余定理:https://www.cnblogs.com/zoeyzy/p/14290815.html 参见我的博客
用(a * b) % p = (a % p * b % p) % p这个公式边取模边算确实可以得到最后结果:
long long normalPower(long long base,long long power){ long long result=1; for(int i=1;i<=power;i++){ result=result*base; result=result%1000; } return result%1000; }
但是仍然有一个时间复杂度的问题,所以就有了下面更高级的算法:
比如要算2的100次方,可以分解为4的50次方,一下子时间就少了近乎一半,再变一变就是16的25次方。
long long fastPower(long long base, long long power) {//base为底数,power为指数 long long result = 1; while (power > 0) { if (power % 2 == 1) { result = result * base % 1000; } power = power / 2; base = (base * base) % 1000; } return result; }
注意假如指数是奇数的话就-1再在下一次循环时除以2,而此时最后结果result应该乘以一次base,时间复杂度就降了非常非常多。
最终版:令我震惊的是这个题居然还可以用位运算,虽然学长讲过一遍但时间久远加没练过题我已经记不太清了=…=
首先可以用power&1判断power的奇偶,得到power二进制时最后一位数字,如果是0则是偶数,是1则是奇数。然后运算power = power / 2时,也可以用位运算,将power的二进制往右边移一位就是它的一半。
上代码:
#include<stdio.h> long long fastPower(long long base, long long power) { long long result = 1; while (power > 0) { if (power & 1) {//此处等价于if(power%2==1) result = result * base % 1000; } power >>= 1;//此处等价于power=power/2 base = (base * base) % 1000; } return result; } int main() { long long base,power; scanf("%lld %lld",&base,&power); printf("%lld",fastPower(base,power)); return 0; }
发现小学期项目完成后对函数没那么抵触了^^,并不会头皮发麻或者手足无措了,事实证明多写写是很有必要的。
与看见博客的你共勉。

浙公网安备 33010602011771号