向前走莫回头❤

【POJ 3070】Fibonacci(矩阵快速幂)

Fibonacci
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 12461   Accepted: 8855

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

An alternative formula for the Fibonacci sequence is

.

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

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:

.

Source

[Submit]   [Go Back]   [Status]   [Discuss]

[题意][求斐波那契数列的第n项]

【题解】【矩阵快速幂】

初始矩阵:F={1,0};   转移矩阵:{1,1},先求转移矩阵的n-2次方,在与初始矩阵相乘,结果为F[0]

                              {1,0}  

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
struct node{
	ll k[2][2];
}a,ans;
ll f[2]={1,0},d1[2],mod=10000;
int n;


inline void clear()
{
	a.k[0][0]=a.k[0][1]=a.k[1][0]=1;a.k[1][1]=0;
}
inline node jc(node a,node b)
{
	node sum;
	int i,j,l;
	sum.k[0][0]=sum.k[0][1]=sum.k[1][0]=sum.k[1][1]=0;
	for(i=0;i<=1;++i)
	 for(j=0;j<=1;++j)
	  for(l=0;l<=1;++l)
	   sum.k[i][j]+=(a.k[i][l]*b.k[l][j])%mod;
	return sum;
}
node poww(node x,int p)
{
	if(p==1) return x;
	if(p==2) return jc(x,x);
	if(!(p%2))
	 {
	 	node t;
	 	t=poww(x,p/2);
	 	t=jc(t,t);
	 	return t;
	 }
	else
	 {
	 	node t;
	 	t=poww(x,p/2);
	 	t=jc(t,t);
	 	t=jc(t,x);
	 	return t;
	 }
}
int main()
{
	int i,j,l;
	while((scanf("%d",&n)==1)&&n!=-1)
	 {
	 	if(!n) {printf("0\n"); continue;}
	 	if(n==1) {printf("1\n"); continue;}
	 	if(n==2) {printf("1\n"); continue;}
		memset(d1,0,sizeof(d1));
	 	clear();
	 	ans=poww(a,n-2);
	 	for(j=0;j<=1;++j)
	 	  for(l=0;l<=1;++l)
	 	    d1[l]=(d1[l]+f[l]*ans.k[l][j]%mod)%mod;
	 	printf("%I64d\n",d1[0]%mod);
	 }
}


posted @ 2016-05-23 07:16  lris0-0  阅读(93)  评论(0编辑  收藏  举报
过去的终会化为美满的财富~o( =∩ω∩= )m