快速幂

 

矩阵

快速幂

求 $3^{13}$

普通方法

  • 常规算法

$3^{13}$ = $3·3·3·3·3·3·3·3·3·3·3·3·3$

需要算 $14$ 次

  • 二分法
\[x^y = \begin{cases} (x^{\frac{y}{2}})^2, & x\ is \ even \\[5ex] x(x^{\frac{y-1}{2}})^2, & x\ is \ odd \end{cases}\]
typedef long long ll;

ll power(int x, int y) {
    if(y & 1) {
        return x * power(x, y-1);
    }
    return power(x * x, y/2);
}

快速

$(13)_{10}$ = $(1101)_2$ = $1$·$2^3$ + $1$·$2^2$ + $0$·$2^1$ + $1$ · $2^0$

$3^{13}$ = $3^{1 * 2^3 + 1 * 2^2 + 0 * 2^1 + 1 * 2^0}$

$3^{13}$ = $3^8$ · $3^4$ · $3^1$

只需要算 $7$ 次

循环次数 底数 指数(二进制) 结果值
$1$ $3^1$ $1101$ $3^1$
$2$ $3^2$ $110$ $3^1$
$3$ $3^4$ $11$ $3^1$ * $3^4$
$4$ $3^8$ $1$ $3^1$ * $3^4$ * $3^8$

快速幂就是对底数进行平方, 遍历指数的每一位, 若指数当前位为 1, 保存当前底数的乘积

typedef long long ll;

// x为底数, y为指数
ll FastPower(ll x, ll y, ll mod) {
    if (y == 0) {
        return 1;
    }
    ll r = 1;
    while (y) {
        // 指数当前位为1, 保存底数乘积
        if (y & 1) {
            r = (r * x) % mod;
        }
        y >>= 1;
        // 底数做平方运算
        x = (x * x) % mod;
    }
    return r;
}

优化 快速乘

long long FastMul(int x, int y) {
    long long r = 0;
    while (y) {
        if (y & 1) {
            r += x;
        }
        y >>= 1;
        x <<= 1;
    }
    return r;
}