您的位置:首页 > 其它

poj3070斐波那契数列求解

2016-09-11 22:41 148 查看

问题

先看下面的问题: [ poj-3070]

Description

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, …

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

Input

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.

Output

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).

Sample Input

0

9

999999999

1000000000

-1

Sample Output

0

34

626

6875

思路

之前讲过的矩阵快速幂求模求解即可。只不过本题在题目描述的过程中给出了另外一种矩阵表示。见下面证明:

[F2F1F1F0]=[1110](1)

由于(1)恒成立,所以当n>=1时,等式两边同乘右边的常数矩阵,有:

[Fn+1FnFnFn−1]=[1110]n(2)

本质是求解如下矩阵:

[1110]n(3)

从而将斐波那契数列问题转化为矩阵乘法的问题,又可以进一步转化为矩阵快速幂。根之前的区别只是最终求解矩阵的区别。

代码

#include <iostream>
#include <cstring>
#include <fstream>
//#define LOCAL
const int maxn = 8;
const int MOD = 10000;

struct Matrix{
int mat_[maxn][maxn];
int size_;

Matrix( int s = 0 ) : size_( s )
{
std::memset( mat_, 0, sizeof(mat_) );
}
Matrix( const Matrix& rhs )
{
size_ = rhs.size_;
*this = rhs;
}
int init()
{
mat_[0][0] = 1;
mat_[0][1] = 1;
mat_[1][0] = 1;
mat_[1][1] = 0;

return 0;
}
int set_diag( int val )
{
for( int i = 0; i < size_; ++i )
{
for( int j = 0; j < size_; ++j )
mat_[i][j] = (i==j)?val:0;
}

return 0;
}
Matrix& operator=( const Matrix& rhs )
{
for( int i = 0; i < size_; ++i )
{
for( int j = 0; j < size_; ++j )
mat_[i][j] = rhs.mat_[i][j];
}
return *this;
}
Matrix operator*( const Matrix& rhs )
{
Matrix ret(2);
for( int i = 0; i < size_; ++i )
{
for( int j = 0; j < size_; ++j )
{
for( int index = 0; index < size_; ++index )
{
ret.mat_[i][j] = (ret.mat_[i][j] +  (mat_[i][index]%MOD * rhs.mat_[index][j]%MOD)%MOD)%MOD;
}
}
}
return ret;
}
Matrix& operator^( int b )
{
Matrix a(*this);
Matrix ans(2);
ans.set_diag(1);
while(b)
{
if(b%2)
ans = ans * a;
a = a*a;
b /= 2;
}
*this = ans;
return *this;
}
};

int main( void )
{
#ifdef LOCAL
std::ifstream cin("input.dat");
#endif
int n = 0;
while( std::cin >> n, n != -1 )
{
if(!n)
std::cout << 0 << std::endl;
else
{
Matrix a(2);
a.init();
a^n;
std::cout << a.mat_[0][1] << std::endl;
}
}
#ifdef LOCAL
cin.close();
#endif
return 0;
}


总结

一遍过,没有遇见太大问题。感受到了引入矩阵后对于问题的简化。矩阵真是个好东西。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: