日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

c语言库快速幂函数,C语言 - 快速幂 - 迭代法+递归法 - 详细讲解

發(fā)布時間:2024/8/23 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言库快速幂函数,C语言 - 快速幂 - 迭代法+递归法 - 详细讲解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

快速冪的作用:

解決 求 a ^ n 的問題 (n可以大于1e18), 如果用for循環(huán)的話,毫無疑問直接炸掉 …… 所以也就用了算法復雜度在 o(log n)的快速冪算法來解決此類問題。

快速冪遞歸法(基于二分思想):

那么既然要用到二分法那么怎么二分? 既然要遞歸那么如何遞歸?

第一個問題如何二分 ?

就以2 ^ 10 為例 , 我們可以以指數(shù)入手進行二分 , 10 是一個偶數(shù) ,那么 二分一下就是 2^5 * 2^5 ,之后 2^5 中 5為奇數(shù) 那么就讓 2^5 = 2 * 2^4 ,那么就有了2^4 ,那么對于 2^4 就又有了偶數(shù)的2 ^ 4進行二分。

初始

二分變化

2^10

2^5 * 2^5

2^5

2 * 2^4

2^4

2^2 * 2^2

2^2

2^1 * 2^1

2^1

2 * 2^0

由可以看出 要對指數(shù)的偶數(shù)和奇數(shù)進行區(qū)分從而進行拆分,這樣可以大大的增大程序的效率,就把 o(n)的算法化成了o(log n)。

第二個問題如何進行遞歸 ?

其實很明了可以看出如果想要遞歸,一定也是以指數(shù)為參數(shù)進行,因為指數(shù)是變化而且牽扯到二分,遞歸的出口就是指數(shù)為零結束,我們可以把奇數(shù)和偶數(shù)進行 if 判斷,如果指數(shù)為偶數(shù)那么就返回 fib(a , b/2 , m), (其中a為底數(shù),b為指數(shù),m為模)。

遞歸法代碼以及解析如下:

#include

using namespace std;

typedef long long ll;

ll binarypow(ll a,ll b,ll m) {

if(b==0) return 1;//如果b為0,那么a^0=1

//b為奇數(shù),轉換為b-1

if(b%2==1) return a*binarypow(a,b-1,m)%m;//可以把if(b%2==1)該為if(b&1)這樣會更快一點。

else {//b為偶數(shù),轉換為b/2;

ll mul=binarypow(a,b/2,m);

return mul*mul%m;

}

}

int main() {

ll a,b,m;

cin>>a>>b>>m;

ll result=binarypow(a,b,m);

cout<

return 0;

}

快速冪迭代法:

迭代法要用到一些二進制,以及位計算的思想,

就如2^13 我們依然以指數(shù)入手,我們可以把13化為二進制 就是 1 1 0 1 我們發(fā)現(xiàn) 1 出現(xiàn)在了 3 號位 , 2 號位 , 以及 0 號位 。

那么 13 = 2^3 + 2^2 + 2^1 = 8 + 4 + 1 ,那么劃開不就是

2 ^ 13 = 2 ^ 8 * 2 ^ 4 + 2 ^ 1

如果把一個指數(shù)這樣進行拆分那么不就可以對

那么問題 1 如何拆分?

問題:如何拆分 ?

我們可以用 if (b & 1) 判斷指數(shù)的末尾是否為 1 (其中b 為指數(shù) ,末尾為1 說明是奇數(shù),末尾為0說明為偶數(shù))如果為 1 那么就讓一個變量乘以當前的 ,例如 變量 :int ans = 1; 讓ans * =a(a為底數(shù)),然后每一次都要a^2 (移到下一位)。然后通過b>>=1把指數(shù)移到下一位判斷下一位的末尾數(shù)是1 ,還是 0 ,然后就這樣進行一步一步的拆分。

文字看不懂的話再加一個表來輔助理解。

b

b & 1

ans

a

1

a

1101

1

1*a

a^2

110

0

a

a^4

11

1

a * a^4

a^8

1

1

a^5 * a^8

迭代法代碼以及解析如下:

#include

using namespace std;

typedef long long ll;

ll binarypow(ll a,ll b,ll m){

ll ans=1;

while(b>0){

if(b&1){//如果b的二進制末尾為1 ,就相當于被選中了。

//就如2^13 ==> 2^(13==>1101)==> 2^(1101) ==> 3 2 0 號為 1 那么被選中 ==> 2^13 = 2^8 * 2^4 * 2^1

ans=ans*a%m;//令ans累積上a

}

a=a*a%m;//令a平方

b>>=1;//將b的二進制右移一位即

}

return ans;

}

int main(){

ll a,b,m;

cin>>a>>b>>m;

ll result=binarypow(a,b,m);

cout<

return 0;

}

總結

以上是生活随笔為你收集整理的c语言库快速幂函数,C语言 - 快速幂 - 迭代法+递归法 - 详细讲解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。