斐波那契遞推式:ios
斐波那契通項公式:算法
求證過程以下:ide
斐波那契和矩陣的關係:spa
描述這個。那仍是描述矩陣和線性遞推式的關係吧3d
線性遞推式。即F(n)和F(n-1),F(n-2),F(n-3),F(n-4)...其階均是一次的關係。code
如F(n)=2F(n-1)+F(n-2).F(n)=F(n-1)+2F(n-3)+4F(n-4)...
blog
矩陣能夠求解這樣的遞推式。也就是說能夠快速計算F(n).時間複雜度能夠到達log(n)級別。string
先介紹一下咱們須要用到的關於矩陣的知識。it
描述矩陣規模時:n行m列。即大小爲n*m.io
矩陣乘法:
形狀上:2*2 和 2*3 的矩陣乘積後,結果是2*3的矩陣。
即 a*b 矩陣 和 c*d的矩陣乘積結果是a*d的矩陣。 其中b和c必須相等。緣由看下面。
運算法則:對於結果矩陣的第i行第j列的位置的結果是由前一個矩陣的對應的行。和後一個矩陣對應的列。對應位置 乘積和得到的。好比第1行第1列的11.是由前矩陣的第一行(1,3)和後矩陣的第一列(2,3)對應位置乘 積和。1*2+3*3 = 11 得到的。若是上述b和c若是不相等。那麼會有地方"失配"沒有數值能夠進行 計算。不符合矩陣乘法定義。
矩陣乘法性質:
矩陣乘法不符合交換律。符合結合律。(具體不分析了。稍加思考即得。)
矩陣的冪運算:
即計算如下式子。
其中樸素想法能夠經過一步一步矩陣乘法來得到結果矩陣。
可是從宏觀角度上去想。咱們把矩陣的乘法理解成一種普通的數的乘法。咱們如今要計算數的冪。
能夠類比快速冪。那麼矩陣也有矩陣的快速冪。分治思想。具體實現其實就是快速冪把乘法那部分改爲矩陣乘法便可。代碼百度上有不少。等下我會放一份。(acdreamer矩陣的模板)
矩陣計算遞推式。
好比:對於F(n)=aF(n-1)+bF(n-2)
咱們能夠構造矩陣和矩陣
兩者乘積爲:
會發現通過一次乘積。咱們能夠得到矩陣。那麼咱們再將這個矩陣乘一次
就會獲得F(3),F(2)的矩陣。因此咱們能夠發現。只要咱們將咱們的初始矩陣乘咱們構造出來的1,1,1,0矩陣n-1次。就能得到F(n),F(n-1)的矩陣。而後F(n)就是咱們想要的了。而乘n-1次1,1,1,0矩陣。根據結合律。咱們可讓1,1,1,0矩陣自乘n-1次。最後再乘初始矩陣便可得到最後咱們想要的結果。
即求。咱們能夠利用快速矩陣冪。就能夠在log(n)複雜度中解決了。
關於斐波那契的一些恆等式:
具體證實:1~4.都是用相似的方法。我提一提。就好吧。
好比1. F(1)=F(3)-F(1) , F(2)= F(4)-F(3)。。。F(n)=F(n+2)-F(n+1)
相似的分解。而後求和就能得到結果了。
對於5.F(n)=F(n-1)+F(n-2)
F(n)=2F(n-2)+F(n-3)
F(n)=3F(n-3)+2F(n-4)
...
F(n)=F(m)F(n-m+1)+F(m-1)F(n-m)
對於6.是個很著名的式子。要想知道證實。百度有好多。就不贅述了。(並且如今還沒用過這個式子。)
斐波那契的數論相關:
性質1:
證實:先證實斐波那契數列相鄰兩項是互素的。
反證法:假設不互素。那麼有a=gcd(F(n),F(n-1)),a>1.
那麼對於F(n)=F(n-1)+F(n-2).由於a|F(n),a|F(n-1),因此a|F(n-2).
因爲a|F(n-1),a|F(n-2).又能夠得到a|F(n-3)...能夠知道a|F(1)其中。F(1)=1.
若是a|F(1)->a|1那麼與a>1不符。相鄰互素得證.(其實 a|F(2)就已經不行了.)
那麼再由上面斐波那契恆等式5.能夠推理。
中間推導依靠一小點數論知識.觀察開始式子和結果。
一直將上式遞推下去。結合gcd(n,m)=gcd(n-m,m).結果會是gcd(a,b) = gcd(0,gcd(a,b))
那麼就能夠證實上述式子成立。
性質2:
證實:當n|m時。
必要性也能夠經過相似手法得證。
1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #include<string> 5 #include<algorithm> 6 #define LL long long 7 #define N 2 8 #define MOD 100000007 9 using namespace std; 10 11 struct Matrix 12 { 13 LL m[N][N]; 14 }; 15 16 Matrix A = { 17 1,1, 18 1,0 19 }; 20 Matrix I = { 21 1,0, 22 0,1 23 }; 24 Matrix multi(Matrix a,Matrix b) 25 { 26 Matrix c; 27 int i,j,k; 28 for(i=0;i<N;i++) 29 { 30 for(j=0;j<N;j++) 31 { 32 c.m[i][j] = 0; 33 for(k=0;k<N;k++) 34 { 35 c.m[i][j] += a.m[i][k] * b.m[k][j] % MOD; 36 } 37 c.m[i][j] %= MOD; 38 } 39 } 40 return c; 41 } 42 Matrix mat_pow(Matrix A,int k) 43 { 44 Matrix ans = I,p = A; //爲了 不更改I 和 A 45 while(k) 46 { 47 if(k&1) 48 { 49 ans = multi(ans,p); 50 } 51 k >>= 1; 52 p = multi(p,p); 53 } 54 return ans; 55 } 56 57 int main() 58 { 59 int n; 60 while(scanf("%d",&n)!=EOF) 61 { 62 Matrix ans = mat_pow(A,n-1); 63 printf("%I64d\n",ans.m[0][0]); 64 65 } 66 return 0; 67 }