星星之火OIer:快速幂、快速积

话说最近在学Miller_Rabin算法,顺便来提一下快速幂和快速积

快速幂和快速积利用了二分的思想

快速幂::

快速幂用字母表示为:a^n,根据幂的运算,可以把a^n转换为a^{\frac{n}{2}}*a^{\frac{n}{2}}

所以这就是快速幂的由来

递归::

简要思路

我们用ans来记录答案(预处理ans=1)每次把指数n/2,先把ans平方,然后如果n是奇数,再把ans*a

代码

int ksm(int a,int b,int n) {//a为底数,b为指数,为模数
    int ans=1;//记录答案
    if(b==1)
        return a%n;//b=1,直接返回a
    ans=(ans*(ksm(a,b/2,n)%n)*(ksm(a,b/2,n)%n))%n//平方后记住取模
    if(b&1)//指数为奇数,还要多乘一个,b&1就是b%2==1的意思
        ans=(ans*a)%n;
    return ans;
}

递推::

简要思路

还是用ans来记录答案,如果n是奇数,就把ans=ans*a,然后再把a平方,当然每次还是要把n/2

代码

int ksm(int a,int b,int n) {//同上
    int ans=1;
    while(b) {//循环
        if(b&1)
            ans=(ans*a)%n;//b为奇数就要乘一次
        a=(a*a)%n;//底数平方一次
        b>>=1;//等价于b/2
    }
}

当然,因为递归需要一层一层深入再一层一层出来,所以时间复杂度相对较高


快速积

快速积和快速幂是一个道理

a*b=(a*b/2)+(a*b/2)

还是有两种方法:

递归

思路就不讲了吧,跟上面是一个道理

int ksc(int a,int b,int n) {//懒得解释了
    int ans=0;
    if(b==1)
        return a;
    ans=(ans+ksc(a,b/2,n)%n*2)%n
    if(b&1)
        ans=(ans+a)%n;
    return ans;
}

递推

int ksc(int a,int b,int n) {
    int ans=0;
    while(b) {
        if(b&1)
            ans=(ans+a)%n;
        a=a*2%n;
        b>>=1;
    }
}

总结

快速幂和快速积其实是非常节省时间的,如果我们直接用power或者直接乘的话,时间复杂度是O(n),而用了快速幂和快速积后,因为是二分,时间复杂度可以降到O(logn),在大数据面前还是很实用

其实这是作者留给自己copy的板

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值