快速幂算法

S S S表示 p p p的二进制权位序列: 2 n , . . . , 2 3 , 2 2 , 2 1 , 2 0 2^n,...,2^3,2^2,2^1,2^0 2n...23222120
B B B表示 p p p的二进制序列。
b p b^p bp可以表示成
b p = ∏ k = 0 n b S k ∗ B k b^p =\prod_{k=0}^{n} b^{S_k*B_k} bp=k=0nbSkBk
T k = b S k ∗ B k T_k=b^{S_k*B_k} Tk=bSkBk
T k = { 1 B k = 0 b 2 k B k = 1 T_k= \begin{cases} 1 &B_k=0 \\ b^{2^k}& B_k=1 \end{cases} Tk={1b2kBk=0Bk=1

可以观察发现,
(1) B k B_k Bk决定了第 k k k T k T_k Tk 是否应该放入累乘中
(2)存在递推关系 T k + 1 = T k ∗ T k T_{k+1}=T_k*T_k Tk+1=TkTk

3 13 3^{13} 313为例。13的二进制序列为1101,从右开始数,0号位为1,1号位为0,2号位为1,3号位为1。则
B = 1 , 1 , 0 , 1 B=1,1,0,1 B=1,1,0,1 S = 2 3 , 2 2 , 2 1 , 2 0 S=2^3,2^2,2^1,2^0 S=23,22,21,20 T = 3 8 , 3 4 , 3 2 , 3 1 T=3^8,3^4,3^2,3^1 T=38,34,32,31,故 3 13 = 3 ∗ 1 ∗ 3 4 ∗ 3 8 3^{13}=3*1*3^4*3^8 313=313438

1,快速幂的迭代法

long long binaryPow(long long b, long long p)
{
    long long r = 1;
    while(p>0)
    {
        if(p & 1)   // 判断p的二进制末位是不是1
        {
            r = r * b;
        }
        p = p >> 1;    // p的二进制右移一位
        b = b * b;
    }
    return r;
}

2,快速幂取余
涉及到同余的性质 a b   m o d   n = [ ( a   m o d   n ) ( b   m o d   n ) ]   m o d   n ab\ mod\ n=[(a\ mod\ n)(b\ mod\ n)]\ mod\ n ab mod n=[(a mod n)(b mod n)] mod n即乘积的模等于乘数模的乘积的模。

long long binaryPowMod(long long b, long long p, long long m)
{
    long long r = 1;
    while(p>0)
    {
        if(p & 1)   // 判断p的二进制末位是不是1
        {
            r = r * b % m;
        }
        p = p >> 1;    // p的二进制右移一位
        b = b * b % m;
    }
    return r;
}

推荐一篇通俗易懂的博客可以参考:快速幂算法从零开始一步一步优化

3.例题

剑指 Offer 16. 数值的整数次方

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值