牛客網-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);
}
}
相關文章
- №20181213賽事:斐波那契數賽題
- 斐波那契數
- 斐波那契數列
- №20201020斐波那契7數賽果確認
- Leedcode-斐波那契數
- 509. 斐波那契數
- 斐波那契數列(Java)Java
- LeetCode 509[斐波那契數]LeetCode
- 一千位斐波那契數
- 斐波那契數列 (C#)C#
- PHP 與斐波那契數列PHP
- python for迴圈和斐波那契Python
- 斐波那契查詢不再迷惑
- LeetCode-509-斐波那契數LeetCode
- 斐波那契數列詳解
- 著名的斐波那契數列
- 如何將斐波那契數列應用到排版設計中
- 大數斐波那契數列的演算法演算法
- №20201020賽事:斐波那契7數+-×÷成立的三層等式
- js實現斐波那契數列JS
- 斐波那契數列演算法演算法
- 第十題:斐波那契數列
- 演算法 - 斐波那契 - javascript 版演算法JavaScript
- LeetCode LCR126[斐波那契數]LeetCode
- [C103] 斐波那契數列
- 力扣之斐波那契數列力扣
- 劍指offer——斐波那契數列
- 斐波那契數列js 實現JS
- 斐波那契數列Ⅳ【矩陣乘法】矩陣
- 計算斐波那契數列的演算法演算法
- 開啟斐波那契數列的新研究大門
- 設計一個程式,列印出1-200之間的斐波那契數列
- 使用Python實現斐波那契數列Python
- 演算法(1)斐波那契數列演算法
- LeetCode 1137第N個斐波那契數LeetCode
- 從斐波那契到矩陣快速冪矩陣
- 斐波那契問題和擴充套件套件
- 【LeetCode刷題】509. 斐波那契數LeetCode