快速冪總結

快速冪總結

快速冪這個東西比較好理解,但實現起來到不老好辦,記了幾次老是忘,今天把它系統的總結一下防止忘記。

  首先,快速冪的目的就是做到快速求冪,假設我們要求a^b,按照樸素算法就是把a連乘b次,這樣一來時間復雜度是O(b)也即是O(n)級別,快速冪能做到O(logn),快了好多好多。它的原理如下:

  假設我們要求a^b,那么其實b是可以拆成二進制的,該二進制數第i位的權為2^(i-1),例如當b==11時

?a11=a(2^0+2^1+2^3)
11的二進制是1011,11 = 23×1 + 22×0 + 21×1 + 2o×1,因此,我們將a11轉化為算 a2^0*a2^1*a2^3,也就是a1*a2*a8?
,看出來快的多了吧原來算11次,現在算三次,但是這三項貌似不好求的樣子....不急,下面會有詳細解釋。 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
?
?
由于是二進制,很自然地想到用位運算這個強大的工具:&和>> ? ?
?
&運算通常用于二進制取位操作,例如一個數 & 1 的結果就是取二進制的最末位。還可以判斷奇偶x&1==0為偶,x&1==1為奇。
?
>>運算比較單純,二進制去掉最后一位,不多說了,先放代碼再解釋。
?
?
復制代碼
 1 int poww(int a,int b){//求a的b次方2     int ans=1,base=a;3     while(b!=0){4         if(b&1!=0)5           ans*=base;6         base*=base;7         b>>=1;8   }9     return ans;
10 }
復制代碼

  代碼很短,死記也可行,但最好還是理解一下吧,其實也很好理解,以b==11為例,b=>1011,二進制從右向左算,但乘出來的順序是?a^(2^0)*a^(2^1)*a^(2^3),是從左向右的。我們不斷的讓base*=base目的即是累乘,以便隨時對ans做出貢獻。

  其中要理解base*=base這一步:因為 base*base==base2,下一步再乘,就是base2*base2==base4,然后同理 ?base4*base4=base8,由此可以做到base-->base2-->base4-->base8-->base16-->base32.......指數正是?2^i ,再看上面的例子,a11= a1*a2*a8,這三項就可以完美解決了,快速冪就是這樣。

  順便啰嗦一句,由于指數函數是爆炸增長的函數,所以很有可能會爆掉int的范圍,根據題意選擇 long long還是mod某個數自己看著辦。

  矩陣快速冪也是這個道理,下面放一個求斐波那契數列的矩陣快速冪模板

復制代碼
 1 #include<iostream>2 #include<cstdio>3 #include<cstring>4 #include<cmath>5 #include<algorithm>6 using namespace std;7 const int mod = 10000;8 const int maxn = 35;9 int N;
10 struct Matrix {
11     int mat[maxn][maxn];
12     int x, y;
13     Matrix() {
14         memset(mat, 0, sizeof(mat));
15         for (int i = 1; i <= maxn - 5; i++) mat[i][i] = 1;
16     }
17 };
18 inline void mat_mul(Matrix a, Matrix b, Matrix &c) {
19     memset(c.mat, 0, sizeof(c.mat));
20     c.x = a.x; c.y = b.y;
21     for (int i = 1; i <= c.x; i++) {
22         for (int j = 1; j <= c.y; j++) {
23             for (int k = 1; k <= a.y; k++) {
24                 c.mat[i][j] += (a.mat[i][k] * b.mat[k][j]) % mod;
25                 c.mat[i][j] %= mod;
26             }
27         }
28     }
29     return;
30 }
31 inline void mat_pow(Matrix &a, int z) {
32     Matrix ans, base = a;
33     ans.x = a.x; ans.y = a.y;
34     while (z) {
35         if (z & 1 == 1) mat_mul(ans, base, ans);
36         mat_mul(base, base, base);
37         z >>= 1;
38     }
39     a = ans;
40 }
41 int main() {
42     while (cin >> N) {
43         switch (N){
44             case -1: return 0;
45             case 0: cout << "0" << endl; continue; 
46             case 1: cout << "1" << endl; continue;
47             case 2: cout << "1" << endl; continue;
48         }
49         Matrix A, B;
50         A.x = 2; A.y = 2;
51         A.mat[1][1] = 1; A.mat[1][2] = 1;
52         A.mat[2][1] = 1; A.mat[2][2] = 0;
53         B.x = 2; B.y = 1;
54         B.mat[1][1] = 1; B.mat[2][1] = 1;
55 
56         mat_pow(A, N - 1);
57         mat_mul(A, B, B);
58         cout << B.mat[1][1] << endl;
59 
60     }
61     return 0;
62 }
復制代碼

?

?

洛谷P1962 斐波那契數列

題目背景

大家都知道,斐波那契數列是滿足如下性質的一個數列:

? f(1) = 1

? f(2) = 1

? f(n) = f(n-1) + f(n-2) (n ≥ 2 且 n 為整數)

題目描述

請你求出 f(n) mod 1000000007 的值。

輸入輸出格式

輸入格式:

?

·第 1 行:一個整數 n

?

?輸出格式:

?

第 1 行: f(n) mod 1000000007 的值

?

輸入輸出樣例

輸入樣例#1:?復制
5
輸出樣例#1:?復制
5
輸入樣例#2:?復制
10
輸出樣例#2:?復制
55

說明

對于 60% 的數據: n ≤ 92

對于 100% 的數據: n在long long(INT64)范圍內。

首先看到數據范圍,longlong以內,故我們考慮矩陣加速動態規劃。

我們都知道斐波那契數列有這樣的一個動態轉移方程:f[i]=f[i-1]+f[i-2];

由此可以推出一個2×2的矩陣:1 1 1 0

然后就是套用矩陣快速冪的模板來加速。

以下是代碼:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;
typedef long long lol;

lol n;
lol mod=1e9+7;
lol f[3][3],ans[3]={0,1,1};

void lu() {
lol t[3]={0};
for (int i=1;i<=2;i++)
for (int j=1;j<=2;j++)
t[i]=(t[i]+(ans[j]*f[j][i])%mod)%mod;
memcpy(ans,t,sizeof(ans));
}

void ge() {
lol t[3][3]={0};
for (lol i=1;i<=2;i++)
for (lol j=1;j<=2;j++)
for (lol k=1;k<=2;k++)
t[i][j]=(t[i][j]+(f[i][k]*f[k][j])%mod)%mod;
memcpy(f,t,sizeof(f));
}

int main() {
cin>>n;
if (n==1||n==2||!n) {
cout<<'1'<<endl;
exit(0);
}
n--;
f[1][1]=1;f[1][2]=1;
f[2][1]=1;f[2][2]=0;
while (n) {
if (n&1) lu();
ge();n>>=1;
}
cout<<ans[2]<<endl;
return 0;
}

?

轉載于:https://www.cnblogs.com/Renyi-Fan/p/8142674.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/453232.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/453232.shtml
英文地址,請注明出處:http://en.pswp.cn/news/453232.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

第三章

一.項目前期的主要工作 1.現狀分析 ①.硬件分析 ②.軟件分析 2.需求收集 3.粗略設計 ①.體系結構分析 ②.硬件&#xff08;網絡&#xff09;設計 ③.應用系統設計 ④.安全設計 ⑤.配套設計 4.可行性分析 二.結構的項目前期實例 1.組織分析 3.需求收集 4.粗略設計 ①.系統體系結…

進程的靜止和活動狀態

進程有3個主要狀態&#xff0c;即就緒&#xff0c;執行和等待。當一個進程被創建的時候&#xff0c;處于就緒狀態&#xff0c;嚴格地說是靜止就緒狀態&#xff0c;等到被激活&#xff0c;該進程就處于活動就緒狀態&#xff0c;如果時間片輪到該進程&#xff0c;那么該進程就執行…

榮耀magic3會用鴻蒙,趙明:榮耀Magic3芯片領先行業,大家看到以后會換掉手機!...

榮耀CEO趙明親自參加高通2021技術峰會&#xff0c;宣布與高通達成戰略合作&#xff0c;未來全系產品采用高通平臺。趙明同時透露未來的產品動向&#xff0c;不排除未來與華為繼續合作&#xff0c;采用鴻蒙操作系統的可能。趙明表示&#xff0c;Android操作系統依舊是榮耀的首選…

公司里從員工到經理,不同層級應該關注的事情

最近在看《領導梯隊》&#xff0c;超級棒的一本書&#xff0c;受益匪淺&#xff0c;推薦給各位從事管理方向的朋友 第一階段&#xff1a;從管理自我到管理他人&#xff08;leader級&#xff09;   新員工工作的最初幾年是個人貢獻者。無論他們從事的是銷售、會計、工程或是市…

繼續教育學習腳本

/* 本腳本運行于瀏覽器conlose中&#xff0c;自動點擊“繼續學習”按鈕&#xff0c;以實現阻止視頻的暫停 */ (function(){ var getStylefunction(obj,styleName){ if(obj.style){ return obj.style[styleName]; }else if(obj.currentStyle){ …

三周第三次課 3.7 su命令 3.8 sudo命令 3.9 限制root遠程登錄

3.7 su命令1、su命令su命令是用來切換用戶的&#xff1b;su命令需要使用- 進行切換&#xff0c;如果不使用- 也可以&#xff0c;但當前目錄是在root下&#xff0c;沒有徹底切換在root下 使用su命令創建文件&#xff0c;以指定用戶的身份創建文件切換后顯示-bash-4.2因為user5的…

js中加載指定的html代碼,在js或JQuery中怎樣判斷頁面html代碼中含有指定名稱的div元素...

在我們制作網頁的過程中&#xff0c;想要在某個頁面中的某一元素中添加新的內容&#xff0c;而不想改動那個頁面,我們一般會直接在全局的jsz中直接加入document.getElementById("指定id")來給定指定元素新的內容,但在一些頁面中沒有指定id的div元素瀏覽器就會報錯&am…

處理機和cpu的區別

處理機 處理機是計算機系統中存儲程序和數據&#xff0c;并按照程序規定的步驟執行指令的部件。程序是描述處理機完成某項任務的指令序列。指令則是處理機能直接解釋、執行的信息單位。處理機包括中央處理器&#xff08;cpu&#xff09;&#xff0c;主存儲器,輸入-輸出接口。處…

三星手機官方固件下載

一&#xff0c;網站下載&#xff1a; https://updato.com/firmware-archive-select-model 查詢對應固件信息 https://www.sammobile.com/firmwares/galaxy-a7/SM-A7000/ http://samsung-updates.com/device/?idSM-A7000&detailsSM-A7000 二&#xff0c;下載器下載&#x…

133. Clone Graph

歡迎fork and star&#xff1a;Nowcoder-Repository-github 133. Clone Graph 題目 Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors.OJs undirected graph serialization:Nodes are labeled uniquely. We use # as a separa…

進程控制塊PCB簡介

PCB(process control block)&#xff0c;進程控制塊&#xff0c;是我們學習操作系統后遇到的第一個數據結構描述&#xff0c;它是對系統的進程進行管理的重要依據&#xff0c;和進程管理相關的操作無一不用到PCB中的內容。一般情況下&#xff0c;PCB中包含以下內容&#xff1a;…

html坐標繪制路徑,canvas學習筆記之繪制簡單路徑

1 線段(直線路徑)繪制線段一般步驟:moveTo(x,y) 移動畫筆到指定的坐標點(x,y)lineTo(x,y) 使用直線連接當前端點和指定的坐標點(x,y)stroke() 根據當前的畫線樣式&#xff0c;繪制當前或已經存在的路徑2 矩形路徑繪制矩形路徑一般步驟:rect(x, y, width, height) 矩形路徑&…

如何實現Punycode中文域名轉碼

如果你見過中文域名應該會覺得很奇怪&#xff0c;為什么復制出來的域名變成一個很莫名其妙的字符串&#xff0c;比如這個秀恩愛的域名“郝越.我愛你”&#xff0c;實際顯示的域名是 http://xn--vq3al9d.xn--6qq986b3xl/ 這就叫 Punycode 具體查看 https://www.punycoder.com/ P…

進程控制塊包含的信息

進程控制塊包含三類信息 1.標識信息。 用于唯一地標識一個進程&#xff0c;常常分由用戶使用的外部標識符和被系統使用的內部標識號。幾乎所有操作系統中進程都被賦予一個唯一的、內部使用的數值型的進程號&#xff0c;操作系統的其他控制表可以通過進程號來交叉引用進程控制…

增加表單的文字段的html的代碼是,表單及表單新增元素(示例代碼)

要想更好運用表單就要了解表單的的更多元素與屬性&#xff0c;首先看看對表單基本了解。表單的基本了解 元素用于用戶輸入數據的收集元素是最重要的表單元素&#xff0c;有許多type其中是用于向表單處理程序提交表單的按鈕。元素 元素定義待選擇的下拉列表選項&#xff0c;元素…

給博客或站點加入百度統計

概述 記得剛接觸百度統計的時候&#xff0c;苦于沒有個人網站&#xff0c;不能加入統計代碼查看訪問量等數據。然后漸漸的忘了這件事。之前看別人博客中提及了百度統計&#xff0c;然后粗略的看了一下加入方法&#xff0c;覺得很驚喜&#xff0c;太簡單了&#xff01; 加入方法…

項目規劃管理

項目規劃管理 - 1 項目規劃是預測未來&#xff0c;確定要達到的目標&#xff0c;估計會碰到的問題&#xff0c;并提出實現目標、解決問題的有效方案、方針、措施和手段的過程。( 摘自百度百科) 大家應該都看過不少美國大片&#xff0c;是否記得很多片子里&#xff0c;特別是偷…

進程控制塊組織方式

進程控制塊PCB的組織方式1&#xff09;線性表方式&#xff1a;不論進程的狀態如何&#xff0c;將所有的PCB連續地存放在內存的系統區。這種方式適用于系統中進程數目 不多的情況。2&#xff09;索引表方式&#xff1a;該方式是線性表方式的改進&#xff0c;系統按照進…

android9叫什么名字,白猜這么多名字!谷歌Android 9.0正式發布:命名Android Pie

日前&#xff0c;谷歌對外公布了Android P的beta版&#xff0c;并向索尼Xperia XZ2、小米Mi Mix 2S、諾基亞7 Plus、Oppo R15 Pro、Vivo X21、一加6和Essential PH-1開放測試。今天&#xff0c;谷歌終于宣布正式發布Android 9.0的正式版本。據外媒GSMArena報道&#xff0c;今天…

靜態鏈接與動態鏈接

靜態鏈接是指把要調用的函數或者過程直接鏈接到可執行文件中&#xff0c;成為可執行文件的一部分。也就是函數和過程的代碼就在程序的可執行文件中&#xff0c;可執行文件包含了運行時所需的全部代碼。動態鏈接是指所調用的函數代碼并沒有被拷貝到應用程序的可執行文件中去&…