快速乘


求一個底數的高次冪取模(a^b%c)時我們會用到快速冪取模,其時間復雜度為logN

然而當兩個大數進行相乘進行取模(a*b%c)時,運算a*b可能會爆long long的范圍,如果會python的同學做這種題目的時候或許不用為此困擾,然而博主這樣不會python的蒟蒻該如何應對這種兩數相乘會爆范圍的情形呢?這時候就需要用到 快速乘 啦!

進入正題:

0.為什么快速乘不會爆范圍,原因如下:

乘法容易爆范圍,但是由於過程中不斷取模,所以加法不會爆范圍。

1.如何用加法實現快速乘?原理如下:

快速乘是利用乘法分配律將a*b分解成多個式子相加(將后面一個乘數轉化為二進制的形式計算)求解。例如:12*11=12*1011(2)=12*2^3+12*2^1+12*2^0=96+24+12=132

2.代碼實現

 

 1 typedef long long LL;
 2 LL mult_mod(LL a,LL b,LL mod)
 3 {
 4  LL res=0;  //注意此處初始化為0不是1
 5  while(b){
 6   if(b&1)res=(res+a)%mod;
 7   a=(a+a)%mod;  //注意此處是加不是乘
 8   b/=2;
 9  }
10  return res;
11 }

 

3.補充說明

按位與運算(&)

按位與運算符"&"是雙目運算符。 其功能是參與運算的兩數各對應的二進位相與。只有對應的兩個二進位均為1時,結果位才為1 ,否則為0。參與運算的數以補碼方式出現。
 
4.快速冪與快速乘的綜合運用
 1 #include<stdio.h>
 2 typedef long long LL;
 3 LL mult_mod(LL a,LL b,LL c)  //快速乘
 4 {
 5  LL res=0;
 6  while(b){
 7   if(b&1)res=(res+a)%c;
 8   a=(a+a)%c;
 9   b=b/2;
10  }
11  return res;
12 }
13 LL pow_mod(LL a,LL b,LL mod)  //快速冪
14 {
15  LL res=1;
16  while(b){
17   if(b&1)res=mult_mod(res,a,mod);
18   res%=mod;
19   a=mult_mod(a,a,mod);
20   a%=mod;
21   b=b/2;
22  }
23  return res;
24 }
25 int main()
26 {
27  LL a,b,mod,sum;
28  scanf("%lld%lld%lld",&a,&b,&mod);
29  sum=pow_mod(a,b,mod);
30  printf("%lld\n",sum);
31  return 0;
32  }

 

 謝謝觀看,如有問題歡迎提出並指正。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM