牛客網-2018年湘潭大學程式設計競賽:G 又見斐波那契
這裡需要使用矩陣快速冪(斐波那契數列的項數n一旦過大,就要考慮矩陣快速冪)。
使用矩陣快速冪的一個關鍵問題就是矩陣遞推式。
可以得到下面這個遞推式了:
我用等式 T^(n+1)=B*T^n,來代替上面的等式
計算矩陣B得到如圖矩陣:
所以T^n=B^(n-1)*T
這樣直接使用矩陣快速冪計算B^(n-1),再B^(n-1)的第一行乘T的第一列,得到 A[n]
程式碼:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
ll mat[][6]={
{1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 0, 0},
{0, 0, 1, 3, 3, 1},
{0, 0, 0, 1, 2, 1},
{0, 0, 0, 0, 1, 1},
{0, 0, 0, 0, 0, 1}
};
ll res[6][6];
ll now[6][6];
int A[]={1, 0, 8, 4, 2, 1};
void mul(ll a[][6],ll b[][6]){
ll c[6][6];
memset(c,0,sizeof(c));
for(int i=0;i<6;i++){
for(int j=0;j<6;j++){
if(a[i][j])
for(int k=0;k<6;k++){
c[i][k]=(c[i][k]+(a[i][j]*b[j][k])%mod)%mod;
}
}
}
for(int i=0;i<6;i++){
for(int j=0;j<6;j++){
a[i][j]=c[i][j];
}
}
}
void mypow(ll n){
memset(res,0,sizeof(res));
for(int i=0;i<6;i++) res[i][i]=1;
for(int i=0;i<6;i++){
for(int j=0;j<6;j++){
now[i][j]=mat[i][j];
}
}
while(n){
if(n&1) mul(res,now);
mul(now,now);
n>>=1;
}
}
int main(){
int T;
scanf("%d",&T);
while(T--){
ll n;
scanf("%lld",&n);
n--;
mypow(n);
ll sum=0;
for(int i=0;i<6;i++){
sum=(sum+res[0][i]*A[i])%mod;
}
printf("%lld\n",sum);
}
}
相關文章
- 斐波那契數
- 斐波那契查詢
- 斐波那契數列
- 斐波那契數列(Java)Java
- js計算斐波那契數列程式碼例項JS
- 斐波那契查詢不再迷惑
- 斐波那契數列 (C#)C#
- PHP 與斐波那契數列PHP
- 斐波那契數列詳解
- Leedcode-斐波那契數
- 斐波那契數列的分治法計算
- 如何將斐波那契數列應用到排版設計中
- js實現斐波那契數列JS
- 斐波那契數列js 實現JS
- 斐波那契數列演算法演算法
- 斐波那契數列Ⅳ【矩陣乘法】矩陣
- 演算法 - 斐波那契 - javascript 版演算法JavaScript
- python for迴圈和斐波那契Python
- 博弈學習 (二) 斐波那契博弈
- 計算斐波那契數列的演算法演算法
- 演算法(1)斐波那契數列演算法
- 斐波那契問題和擴充套件套件
- 從斐波那契到矩陣快速冪矩陣
- 博弈論入門之斐波那契博弈
- 高效率JAVA實現斐波那契Java
- 面試題9-斐波那契數列面試題
- 斐波那契數(C/C++,Scheme)C++Scheme
- [C103] 斐波那契數列
- 某大學程式設計競賽程式設計
- 使用Python實現斐波那契數列Python
- JavaScript 實現:輸出斐波那契數列JavaScript
- js迭代器實現斐波那契數列JS
- LeetCode-509-斐波那契數LeetCode
- 演算法一:斐波那契阿數列演算法
- 斐波那契數列的python實現Python
- 設計一個程式,列印出1-200之間的斐波那契數列
- 2014年北京師範大學新生程式設計競賽網路賽程式設計
- 斐波那契數列三種實現函式函式