快速积 & 快速幂
快速幂
问题:计算\(x^n ( -2^{31} < n < 2^{31}-1)\)
最直接的方式是基数1乘以x并循环n次,但n很大时效率很低,由此引出快速幂。 简单理解就是:\(x^n = x * x^2*x^4*x^8...x^{2^m}\)。考虑\(n > 0\)的情况,举例说明\(3^9\)怎么计算。其中\(n = 9 = 1001_b =1 * 2^0 +0 * 2^1+ 0 * 2^2+ 1 * 2^3\),故:
\[3^9 = 3 ^{1 * 2^0 +0 * 2^1+ 0 * 2^2+ 1 * 2^3} = 3 ^{1 * 1} * 3^{0 *2} * 3^{0*4}*3^{1*8} = 3 ^{1 * 1} *3^{1*8}
\]
发现对应的指数恰好是n二进制位的权重乘以二进制位。代码实现:
double quickPow(double x,int n){
double ans = 1.0;
while(n > 0){
if((n & 1) == 1){
ans *= x;
}
x *= x;
n >>= 1;
}
return ans;
}
整数快速幂并求模
要求最终结果对某个数如1e9+7求模,程序稍微有些不同
public int quickPow(long x, int m){
int MOD = (int)(1e9+7);
long res = 1;
while(m > 0){
if((m&1)==1) res = (res * x) % MOD;
x = (x * x) % MOD ;
m >>= 1;
}
return (int)res;
}
快速积
计算机计算a*b是利用二进制进行计算,如果是大数运算效率也不好。为此快速积发挥作用。还是利用二进制,举例说明\(3*9= 3 *1001_b = 3 *(2^0 + 2^3)\)
double quickMultiply(int a,int b){
int ans = 0;
while(b > 0){
if((b & 1) == 1){
ans += a;
}
a += x;
n >>= 1;
}
return ans;
}