【ACM数论】快速幂

快速幂

通常地,我们计算 a x a^x ax是将 x x x从1一直累乘到 x x x,这样是最简单的计算方法,但是这种做法的时间复杂度是 o ( n ) o(n) o(n),一旦我们计算的幂次方较大或者计算次数较多的时候就会花费很长的时间;例如:计算 1 0 100000000 10^{100000000} 10100000000组类似 99 9 100000000 999^{100000000} 999100000000这样的计算式,你可能算一辈子都算不出来。

​ 这个时候引入二进制对 a x a^x ax进行优化:

​ 考虑 a 2 x a^{2x} a2x= a x × a x a^x×a^x ax×ax= ( a x ) (a^x) (ax) 2 ^2 2于是可以利用二进制表示分割成更小的一部分

​ 例如: 9 13 9^{13} 913= 9 ( 1101 ) 2 9^{(1101)_2} 9(1101)2= 9 8 9^8 98× 9 4 9^4 94× 9 1 9^1 91

​ 因为 n n n [ l o g 2 x ] + 1 [log_2x]+1 [log2x]+1个二进制位,因此当我们知道了 a 1 , a 2 , a 4 . . . a 2 k a^1,a^2,a^4...a^{2^k} a1,a2,a4...a2k后,我们只用计算 [ l o g 2 x ] + 1 [log_2x]+1 [log2x]+1次乘法就可以计算出 a x a^x ax

​ 因此计算 a x a^x ax只需要将 x x x对应的二进制下的数位为1的整系数幂乘起来即可

​ 即: a x a^x ax= a ( x 0 x 1 x 2 . . x n ) 2 a^{(x_0x_1x_2..x_n)_2} a(x0x1x2..xn)2= a x 0 2 0 a^{x_02^{0}} ax020× a x 1 2 1 a^{x_12^{1}} ax121× a x 2 2 2 a^{x_22^{2}} ax222…× a x n 2 n a^{x_n2^{n}} axn2n

​ 根据上式发现,原问题被转化成了形式相同的子问题的乘积,并且我们可以在常数时间内从 2 i 2^i 2i 项推出 2 i + 1 2^{i+1} 2i+1项。

​ 通过二进制处理后时间复杂度降为 O ( l o g n ) O(logn) O(logn)

​ 下面是我的快速幂代码模版:

long long fastpow(long long a, long long n) //快速幂
{
    long long ans = 1;
    while (n)
    {
        if (n & 1)
        {
            ans *= a;
        }
        a *= a;
        n >>= 1; //位运算
    }
    return ans;
}
  • 24
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值