快速幂
为降低原来O(b)的时间复杂度,求解a^b%m,现在利用二分的思想,进行求解。
a^b=a *a^(b-1) b为奇数
ab=a(b/2)*a^(b/2) b为偶数
在经过O(ln(b))级别的转换后,就可以将b变成0;
还要必须知道的是 a b…n%m=(a%m)(b%m)…(n%m)%m.
另外%,/ ,*的优先级一样。
#include<cstdio> typedef long long LL; LL binaryPow(LL a,LL b,LL m) { if (b == 0) return 1; if (b & 1) return a * binaryPow(a, b - 1, m) % m; else { LL mul = binaryPow(a, b / 2, m); return mul * mul%m;//此处不要返回binaryPow(a, b / 2, m)*binaryPow(a, b / 2, m);因为这样每次都会调用两个binaryPow(a, b / 2, m),导致复杂度变为O(b). } }
添加两个细节:
如果初始的时候a有可能大于等于m;那么需要在进入函数之前就让a对m取模。ab…n%m=(a%m)(b%m)…(n%m)%m.
如果m=1,可以直接在函数外面判断特例为0;
下面是快速幂的迭代的写法。
对于a^b,可以把b写成二进制,那么b就可以写成若干二次幂之和。
例如:
13==》1101;三号位,二号位,零号位都为1,则 13=2^3 +2^2 +2^0=8+4+1;
a^13=a^8*a^4*a^1;
typedef long long LL; LL binaryPow(LL a,LL b,LL m) { LL ans = 1; while (b > 0) { if (b & 1) { ans = ans * a %m; } a = a * a % m; b >>= 1; } return ans; }
当b=13时可有以下过程


浙公网安备 33010602011771号