O(lgn)计算斐波那契数

1、斐波那契数按如下递推式定义

f(0)=f(1)=1

f(n)=f(n-1)+f(n-2), n>=2

2.常规的求斐波那契数时间复杂度为O(n),直接用递推式求

f[0]=f[1]=0;
for(i=2;i<n;i++)
	f[i]=f[i-1]+f[i-2];

或者先求出通项公式,特征值为x1,x2,则

f(n)=A*x1^n+B*x2^n

3.现在主要讨论O(lgn)时间复杂度的解,看到这个复杂度,马上想到二分法。用一维数组代替2*2的矩阵,矩阵乘法表示为

{f(n-1),f(n),f(n-1),f(n)}*{0,1,1,1}=f{f(n),f(n+1),f(n),f(n+1)}

矩阵乘法的代码

int* mult(int *A,int *B) {
	int* C=new int[4];
	C[0]=A[0]*B[0]+A[1]*B[2];
	C[1]=A[0]*B[1]+A[1]*B[3];
	C[2]=A[2]*B[0]+A[3]*B[2];
	C[3]=A[2]*B[1]+A[3]*B[3];
	return C;
}
递归求矩阵A^n的二分法为

int* A_n(int *A,int p,int q) {
	if(p==q)	return A;
	else {
		int r=(p+q)/2;
		return mult(A_n(A,p,r),A_n(A,r+1,q));
	}
} 

测试代码

int main() {
	int f[4]={1,1,1,1};
	int B[4]={0,1,1,1};
	int *fn;
	int *f1=f,*B1=B;
	int n;
	while(cin>>n) {
		fn=mult(f1,A_n(B1,0,n-1));
		cout<<fn[0]<<endl;
	}
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值