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 is:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...
An alternative formula for the Fibonacci sequence is
.
Given an integer n, your goal was to compute the last 4 digits of Fn.
Input
The input test file would contain multiple test cases. Each of the test case consists of a 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 is all zeros, print ' 0 '; Otherwise, omit any leading zeros (i.e., print Fn mod 10000).
Sample Input
099999999991000000000-1
Sample Output
0346266875
Hint
As a reminder, matrix multiplication is associative, and the product of the A/2x2 matrices is given by
.
Also, note that raising any 2×2 matrix to the 0th power gives the identity matrix:
.
Moment by Explanation:
Direct recursion computation time complexity is obviously O (n), while the subject n<=1e9, direct recursion obviously timed out
We know that by asking for FIB (n), we only need to know the FIB (n-1) and fib (n-2), we only need to save the last two Fibonacci numbers when recursion
Set f (n) to represent a 1*2 matrix, f (n) = {f (n), F (n+1)}
We want to calculate f (n) based on f (n-1) = {f (n-1), f (N)}. We set up a matrix a {0,1},{1,1}, then: F (N) =f (n-1) *a=f (1) *an-1
The second side of a, you can use fast power optimization? Simply optimize O (n) to O (23log (n))
Code
#include <stdio.h>#include<string.h>#include<algorithm>#definell Long Longusing namespacestd;Const intMod=10000;intK;voidMul (LL f[2],ll ju[2][2]) {ll c[2];memset (c,0,sizeof(c)); for(intI=0;i<2;++i) for(intj=0;j<2;++j) C[i]= (C[i]+f[j]*ju[j][i])%MoD; memcpy (F,c,sizeof(c));}voidMulself (LL ju[2][2]) {ll c[2][2];memset (c,0,sizeof(c)); for(intI=0;i<2; ++i)//line I for(intj=0;j<2; ++j)//Column J for(intk=0;k<2;++k) C[i][j]= (C[i][j]+ju[i][k]*ju[k][j])%MoD; memcpy (Ju,c,sizeof(c));}intMain () { while(SCANF ("%d", &k)! =EOF) { if(k==-1) Break; ll f[2]={0,1}; ll ju[2][2]={{0,1},{1,1}}; while(k) {if(k&1) Mul (F,ju); Mulself (JU); K>>=1; } printf ("%lld\n", f[0]); } return 0;}
Fibonacci "Matrix multiplication" (POJ 3070)