NYOJ0148-fibonacci数列(二)

fibonacci数列(二)

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 3
描述

In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn − 1 + Fn − 2 for n ≥ 2. For example, the first ten terms of the Fibonacci sequence are:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …

An alternative formula for the Fibonacci sequence is

.

Given an integer n, your goal is to compute the last 4 digits of Fn.

Hint

As a reminder, matrix multiplication is associative, and the product of two 2 × 2 matrices is given by

.

Also, note that raising any 2 × 2 matrix to the 0th power gives the identity matrix:

.

输入
The input test file will contain multiple test cases. Each test case consists of a single line containing n (where 0 ≤ n ≤ 1,000,000,000). The end-of-file is denoted by a single line containing the number −1.
输出
For each test case, print the last four digits of Fn. If the last four digits of Fn are all zeros, print ‘0’; otherwise, omit any leading zeros (i.e., print Fn mod 10000).
样例输入
0
9
1000000000
-1
样例输出
0
34
6875

    运用部分矩阵快速幂的知识,如果不太了解与斐波那契相关的矩阵快速幂,可以 点这儿

#include <stdio.h>
#include <string.h>
#define Mod 10000
using namespace std;

struct Matrix {
	
	int arr[2][2];

	//构造函数1:初始化为0
	Matrix () {
		memset( this->arr,0,sizeof(this->arr) );
	}

	//构造函数2:初始化为一个int[2][2]的数组
	Matrix ( int c[2][2] ) {
		for( int i=0 ; i<2 ; i++ ) {
			for( int j=0 ; j<2 ; j++ ) {
				this->arr[i][j] = c[i][j];
			}
		}
	}

	//加
	Matrix add( Matrix b ) {
		Matrix c;
		for( int i=0 ; i<2 ; i++ ) {
			for( int j=0 ; j<2 ; j++ ) {
				c.arr[i][j] = ( this->arr[i][j] + b.arr[i][j] ) % Mod;
			}
		}
		return c;
	}

	//减
	Matrix sub( Matrix b ) {
		Matrix c;
		for( int i=0 ; i<2 ; i++ ) {
			for( int j=0 ; j<2 ; j++ ) {
				c.arr[i][j] = ( this->arr[i][j] - b.arr[i][j] ) % Mod;
			}
		}
		return c;
	}

	//乘
	Matrix mul( Matrix b ) {
		Matrix c;
		for( int i=0 ; i<2 ; i++ ) {
			for( int j=0 ; j<2 ; j++ ) {
				for( int k=0 ; k<2 ; k++ ) {
					c.arr[i][j] = c.arr[i][j] + ( this->arr[i][k] )*b.arr[k][j] % Mod;
				}
				c.arr[i][j] %= Mod;
			}
		}
		return c;
	}

	//矩阵快速幂
	Matrix quickPow( int n ) {
		if( n==1 )
			return *this;
		Matrix c = *this;
		Matrix ans = *this;
		while( n ) {
			if( n&1 )
				ans = ans.mul(c);
			c = c.mul(c);
			n = n >> 1;
		}
		return ans;
	}

	//矩阵输出
	void out() {
		for( int i=0 ; i<2 ; i++ ) {
			for( int j=0 ; j<2 ; j++ ) {
				printf( "%d ",this->arr[i][j] );
			}
			printf("\n");
		}
	}

};

int f[2][2] = { 1,1,1,0 };
Matrix c = f;

int main() {
	int n;
	while( ~scanf( "%d",&n ) && n>=0 ) {
		if( n==0 ) {
			printf( "0\n" );
		} else {
			Matrix ans;
			ans = c.quickPow(n-1);
			printf( "%d\n",ans.arr[1][0] );
//			ans.out();
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值