【POJ 3070】Fibonacci(矩阵快速幂)
Fibonacci
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);
}
}