快速幂和慢速乘

我们知道,求幂运算的方法

int ans=1;
for(int i=1;i<=power;i++)
	ans*=base;

不过这样有个问题,就是在(2,32)的时候就会爆int 而long long 也在(2,64)的时候不能幸免,所以很多时候我们求的是幂运算的mod后的结果比如这样写

int ans=1;
for(int i=1;i<=power;i++)
	ans*=base%mod;

就可以解决数据范围的问题,但是当power很大的时候,时间就成了约束条件,如当power为1e9时,时间达到了15s。那么我们如何解决这样问题呢?
快速幂就派上用场了
我们知道时间慢的原因是因为乘的动作循环了1e9次,我们要想优化,必须把乘的次数减少。快速幂的关键就在这

比如2100=(22)50
我们用50+1次操作替代了100次操作,同时我们可以继续递归下去减少时间
(22)50=((22)2)25
用25+2次操作替代了51次
那么接下来应当怎么做呢25无法再整除2了,因此我们可以把它变成((22)2)24+1=(22)2)24 * (22)2)=(((22)2)2)12 * (22)2
在编程中如何实现呢?
用位运算比较容易理解,比如pow(2,9),9用二进制表示为10001,2power=(22)power/2,可以通过每次power/=2.base*=base来化简,如果二进制最后一位为1,那么不能直接化简要把1提出来,就是ans要乘以base。

int q_pow(int base,int power,int mod)
{
    int ans=1;
	while(power)
    {
        if(power&1)
        	ans=ans*base%mod;
        base=base*base%1000;
        power>>=1;
    }
    return ans;
}

在这里插入图片描述
十分快的得到了结果

和快速幂类似,如果直接乘会爆long long,那么可以用慢速乘

ll q_mul(ll x,ll y,ll mod)
{
    ll ans=1;
    while(y)
    {
        if(y&1) ans=(ans+x)%mod;
        x=(x*2)%mod;
        y>>=1;
    }
    return ans;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值