快速幂快速乘
Posted -ackerman
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快速幂快速乘相关的知识,希望对你有一定的参考价值。
在ACM的比赛中,我们经常会遇到指数型的数据的取模问题。
如果我们直接对数据进行取模,由于题目所给的数据的范围很大,会导致爆int 或者 long long
所以我们要采取快速幂取模
先看一组例子:
2*2*2*2*2*2*2*2*2*2*2
我们可以这样去算
原式=4*4*4*4*4*2
=8*8*4*2
=16*4*2
就是先合并后计算,这样就可以减少计算的步骤
快速幂的基本理论: 积的取余等于取余的积取余
快速幂就是我们先不断的降低a,b的规模,然后再进行计算
a^b
降低a的规模: 只要让 a变成a*a
降低b的规模: 如果b是偶数,那么每次a=a*a之后,b=b/2
如果b是奇数,那么我们就先把这个多出来的数先跳出来,然后再用偶数的处理方法
从而我们就可以得到快速幂的代码了!
LL mul(LL a,LL b) LL sum = 1; a = a % mod; while (b>0) if (b%2==1) // b是奇数 sum = (a*sum)%mod; a = (a*a) % mod; b = b/2; sum = sum%mod; return sum;
这里我们再讲一个快速乘,也可以说是大数乘法
快速乘法使用二进制将乘法转化为加法,既加快可以加快运算速度,又可以防止直接相乘之后溢出
LL mul(LL a,LL b) LL ans = 0; a = a % mod; while (b) if (b & 1) // b是奇数 ans = (ans + a) % mod; a = (a + a) % mod; b >>= 1; return ans;
既然已经知道了快速乘 为什么不用快速乘去优化下我们的快速幂呢?
ll mul(ll a,ll b,ll mod) a%=mod; b%=mod; ll res=0; while(b) if(b&1) res+=a; if(res>=mod) res-=mod; b>>=1; a<<=1; if(a>=mod) a-=mod; return res; ll quickPow(ll a,ll b,ll m) ll res=1; while(b) if(b&1) res=mul(res,a,m); a=mul(a,a,m); b>>=1; return res;
以上是关于快速幂快速乘的主要内容,如果未能解决你的问题,请参考以下文章