今天做了到题要用到慢速乘,然后发现自己的快速幂一直记得模板,没有弄懂原理= =
快速幂:
假设对于a^11,我们把11换成二进制11->1011
那么a^11=a^8*a^2*a^1,转化成二进制之后,我们只用维护一个底数,就像十进制乘法那样。
ll ksm(ll a,ll b,ll p){
ll ans=1,ret=a;
for(;b;b>>=1){
if(b&1)(ans*=ret)%=p;
(ret*=ret)%=p;
}
return ans;
}
俄罗斯农民乘法(慢速乘):
对于a*11:
a*11=a*(2^3+2^1+2^0),类似于快速幂。
ll mult(ll a,ll b,ll p){
ll ans=0,ret=a;
for(;b;b>>=1){
if(b&1)(ans+=ret)%=p;
(ret<<=1)%=p;
}
return ans;
}
十进制乘法:
对于a^233666:
a^233666=a^200000*a^30000*a^3000*a^600*a^60*a^6
ll _10system(ll a,int *b,int len,ll p){
ll ans=1,ret=a;
for(int i=1;i<=len;++i){
(ans*=ksm(ret,b[i]))%=p;
ret=ksm(ret,10);
}
return ans;
}