HELLO WORLD--一起加油(🍺)!|

kingwzun

园龄:3年6个月粉丝:111关注:0

快速幂算法+取模

快速幂

用途: 顾名思义,快速幂就是很快速的幂运算,
复杂度: O(logn)
实现原理:
image
规律:

  • 如果指数是偶数,直接将底数平方,指数处以2;
  • 如果指数是奇数,将底数平方,指数除以2,再乘上底数。

模板代码:

ll qpow(ll a,ll b) //a是底数,b是指数
{
ll ans=1;//ans是结果的系数
while(b)
{
if(b%2==1)
{
ans=ans*a;
}
b/=2;
a=a*a;
}
return ans;
}

位运算优化代码:

ll qpow(ll a,ll b)
{
ll ans=1;
while(b)
{
if(b&1)
{
ans=ans*a;
}
a=a*a;
b>>=1;
}
return ans;
}

快速幂取模公式:
(a×b)%m = ((a%m)×(b%m))%m;
推广:
  (a × a × a...)%c
 = ( (a%c)×(a%c)×(a%c)×... )%c
 = (a%c)b %c;

取模模板代码:

ll qpow(ll a,ll b)
{
ll ans=1;
a%=mod;
while(b)
{
if(b%2==1)
{
ans=(ans*a)%mod;
}
b/=2;
a=(a*a) %mod;
}
return ans;
}

位运算优化代码:

ll qpow(ll a,ll b)
{
ll ans=1;
a%=mod;
while(b)
{
if(b&1)
ans=ans*a%mod;
b>>=1;
a=a*a%mod;
}
return ans;
}

龟速乘

因为本来两个数相乘的时间复杂度是O(1),而用了这种方法后时间复杂度变为了O(logN),故称龟速乘。

作用: 用于两个大数相乘还要求取模的情况。

实现方式:
将其中一个乘数分解成2的幂次相加,

比如数字5的二进制表示为101,我们把它看成是22+20,则5 * a可以看成22a+20a,这就是龟速乘。

代码

#include <iostream>
using namespace std;
typedef long long LL;
LL qadd(LL a, LL b, LL p)
{
LL res = 0;
while (b)
{
//将变量b看成是二进制形式,若当前位为1,则更新取模的结果
if (b & 1) res = (res + a) % p;
b >>= 1;
a = (a + a) % p;
}
return res;
}
int main()
{
LL a, b, p;
cin >> a >> b >> p;
cout << qadd(a, b, p) << endl;
return 0;
}

本文作者:kingwzun

本文链接:https://www.cnblogs.com/kingwz/p/15257654.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   kingwzun  阅读(772)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起