快速幂算法+取模
快速幂
用途: 顾名思义,快速幂就是很快速的幂运算,
复杂度: O(logn)
实现原理:
规律:
- 如果指数是偶数,直接将底数平方,指数处以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,我们把它看成是,则5 * a可以看成,这就是龟速乘。
代码
#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 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步