[[TOC]]

解释

现在我们需要求basebbase ^ b,显然最简单的方法就是执行bb次for循环,但如果bb很大,例如10910^9,就会超时.

显然: ++任意一正整数都可以唯一的表示成若干个不重复的2的次幂的和++,也就是可以唯一的写成对应的二进制形态.

那么如果设bb在二进制状态下有kk位,设第i(0i<k)i(0 \leqslant i < k)表示成cic_i,ci0,1c_i \in {0,1},那么bb可以表示成如下

b=ck12k1+ck22k2++c020(1) b =c_{k-1} 2^{k-1} + c_{k-2} 2^{k-2} + \cdots + c_0 2^0 \tag 1

结合指数幂分配律: am+n=am×ana^{m+n} = a^m \times a^n

ab=ack12k1×ack22k2++ac020(2) a ^ b = a^{c_{k-1} 2^{k-1}} \times a^{c_{k-2} 2^{k-2}} + \cdots + a^{c_0 2^0} \tag 2

再根据幂乘方律: (am)n=amn(a^m)^n = a^{mn},所以a2i=a2i12=(a2i1)2a^{2^i} = a^{2^{i-1} \cdot 2} = (a^{2^{i-1}})^2,也就是说aba^b是的相邻两项是"倍之"的关系.

又一个显然的数学常识,整数bb的二进制的位数有log2(b+1)\lceil log_2^{(b+1)} \rceil,也就说aba^b最多有log2(b+1)\lceil log_2^{(b+1)} \rceil个项.

代码模板

综上,可以写下面的代码.

//口决: 是1就乘,base增增
template<typename  T =long long>
T quick_pow(T base, T b ,T mod) {
    T ans = 1 % mod; //防止 mod 是 1
    for(; b; b>>=1)
    {
        if(b & 1)
            ans = ans * base % mod;
        base = base * base % mod;
    }
    return ans;
}

口诀

是1就乘,base增增(倍之)

题目

暂无题目