M斐波那契數列
此題對數學基礎要求較高
來源矩陣乘法_百度百科
一個m*n的矩陣是一個由m行n列元素排成的矩形陣列。矩陣裏的元素可以是數字符號或者數學式.
形如 的數表稱爲二階矩陣,其中a,b,c,d稱爲這個矩陣的元素。
形如 的有序對稱爲列向量
設
則
稱爲二階矩陣A與平面向量B的乘積,記爲AB=C
更一般的矩陣乘法如下
設A爲 的矩陣,B爲 的矩陣,那麼稱 的矩陣C爲矩陣A與B的乘積,,其中矩陣C中的第 行第 列元素可以表示爲:
如下所示:
我們知道斐波那契數列的遞推公式
因此我們可以寫出以下式子
將每一項的係數寫成一個矩陣
由矩陣乘法的特性可知
由此可推出(或找規律)
因此只要計算出 ,然後取左上角值就可以了
矩陣定義如下:
struct matrix {
int n;
int m;
long long a[SIZE][SIZE];
matrix() {
n=2;
m=2;
memset(a,0,sizeof(a));
}
matrix(int x,int y) {//構造函數
n=x;
m=y;
memset(a,0,sizeof(a));
}
void print() {
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
printf("%d ",a[i][j]);
}
printf("\n");
}
}
void setv(int x) {//矩陣初始化
if(x==0) {
memset(a,0,sizeof(a));
}
if(x==1) {
memset(a,0,sizeof(a));
for(int i=1; i<=n; i++) a[i][i]=1;
}
}
friend matrix operator *(matrix x,matrix y) {//矩陣乘法
matrix tmp=matrix(x.m,y.m);
for(int i=1; i<=x.n; i++) {
for(int j=1; j<=y.m; j++) {
tmp.a[i][j]=0;
for(int k=1; k<=y.n; k++) {
tmp.a[i][j]+=(x.a[i][k]*y.a[k][j])%mod;
// tmp.a[i][j]%=mod; 取模次數太多會TLE!
}
tmp.a[i][j]%=mod;
}
}
return tmp;
}
};
矩陣快速冪:
(跟整數的快速冪幾乎一樣)
matrix fast_pow(matrix x,int k) {
matrix ans=matrix(2,2);
ans.setv(1);
while(k>0) {
if(k&1) {
ans=ans*x;
}
k>>=1;
x=x*x;
}
return ans;
}