快速积 & 快速幂

快速幂

问题:计算\(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;
}
posted @ 2022-08-05 16:30  wenchu1995  Views(55)  Comments(0Edit  收藏  举报