取英文首字母来命名函数名称:
(1) multiply乘;(2) power-幂;(3) quick-快速;(4) mod-取模
①快速乘
由于计算机底层设计的原因,做加法往往比乘法快的多,因此将乘法转换为加法计算将会大大提高乘法运算的速度,除此之外,当我们计算 a*b%mod 的时候,往往较大的数计算 a*b 会超出long long int的范围,这个时候使用快速乘法方法也能解决上述问题。
快速乘法的原理就是利用乘法分配率来将a*b转化为多个式子相加的形式求解(注意这时使用乘法分配率的时候后面的一个乘数转化为二进制的形式计算)
eg:20*14 = 20*(1110)2 = 20*(2^3)*1 + 20*(2^2)*1+20*(2^1)*1+20*(2^0)*0 = 160+80+40 = 280
typedef long long ll; ll qm(ll a,ll b) { ll ans=0; while(b) { if(b&1) ans+=a; b>>=1; a<<=1; } return ans; }
②快速乘取模
typedef long long ll; ll qmm(ll a,ll b,ll mod) { ll ans=0; while(b) { if(b&1) ans=(ans+a)%mod; a<<=1; b>>=1; } return ans; }
③快速幂
typedef long long ll; ll qp(ll x,ll p) { ll ans=1; while(p) { if(p&1) ans*=x; p>>=1; x*=x; } return ans; }
④快速幂取模(二阶),即求(x^p)%mod
typedef long long ll; ll qpm(ll x,ll p,ll mod) { ll ans=1; while(p) { if(p&1) ans=ans*x%mod; p>>=1; x=x*x%mod; } return ans; }
⑤快速幂取模(三阶),即求(a^(b^c))%mod
三阶和二阶的函数一样,只是输出方程有变:qpm(a,qpm(b,c,mod-1),mod);
⑥快速幂取模+快速乘取模(最优)
typedef long long ll; ll qmm(ll a,ll b,ll mod) { ll ans=0; while(b) { if(b&1) ans=(ans+a)%mod; b>>=1; a=(a<<1)%mod; } return ans; } ll qpm(ll x,ll p,ll mod) { ll ans=1; while(p) { if(p&1) ans=qmm(ans,x,mod); p>>=1; x=qmm(x,x,mod); } return ans; }