算法設計與分析 1.2 不一樣的fibonacci數列


★題目描述

fibonacci 數列的遞推公式是F(n) = F(n-1) + F(n-2)(n >= 2 且 n 為整數)。

將這個遞推式改為F(n) = aF(n-1) + bF(n-2)(n >= 2 且 n 為整數)時得到的是怎樣的數列。

注意,這里我們依然令 F(0)=F(1)=1。

★輸入格式

輸入第一行三個正整數 q, a, b。

接下來有 q 行,每行一個自然數 n。

對於50%的數據,1 <= q、n <= 1000。

對於80%的數據,1 <= q、n <= 100000。

對於100%的數據,1 <= q <= 100000,1 <= n <= 1000000000,1 <= a、b <= 1000。

★輸出格式

對於操作2,輸出一個整數,表示對應的元素。

★樣例輸入

5 4 5
2
4
8
16
32

★樣例輸出

9
209
1377
182
9

★參考代碼

思路參考自共享文件

/*
可以使用遞歸或用數組+循環的方法
但是這種方法必定超時

所以必須優化,使用矩陣求法
進行公式推導: 
 f[n]        [a b]    f[n-1]     [a  b]^n-1   f[1]
       =           *          =             * 
f[n-1]       [1 0]    f[n-2]     [1  0]       f[0]

所以核心是 
[a  b]^n-1
[1  0]

現在問題轉化為快速求矩陣的冪,原理如下,例如
A8 = A4*A4 = A2*A2*A4   時間降為log(n) 
*/
#include<bits/stdc++.h>
using namespace std;

int q,a,b;
const int mod=2013;

class Matrix{
private:
	int a11,a12,a21,a22; 
	
public:
	Matrix(){}
	Matrix(int a,int b,int c,int d){
		a11=a%mod;
		a12=b%mod;
		a21=c%mod;
		a22=d%mod;
	}
	Matrix operator *(const Matrix &m){
		return Matrix(a11*m.a11+a12*m.a21, a11*m.a12+a12*m.a22,
					  a21*m.a11+a22*m.a21, a21*m.a12+a22*m.a22); 
	}
	int getRes(){
		return (a11*1+a12*1)%mod; 
	}
}; 

int fib(int n){
	Matrix resM(1,0,0,1); //單元矩陣 
	Matrix M(a,b,1,0);
	while(n>0){
		if(n&1) resM = resM*M;//如果n不是偶數
		M=M*M;
		n>>=1; //n縮小2倍 
	}
	return resM.getRes(); 
}

int main(){	
	cin>>q>>a>>b;
	
	int n;
	while(q--){
		scanf("%d",&n);
		printf("%d\n",fib(n-1));	
	}
	return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM