Fibonacci
Description
In the Fibonacci integer sequence, F 0 = 0 F_0=0 F0=0, F 1 = 1 F_1=1 F1=1, and F n = F n − 1 + F n − 2 F_n = F_{n-1}+F_{n-2} Fn=Fn−1+Fn−2for n > = 2 n>=2 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
[
F
n
+
1
F
n
F
n
F
n
−
1
]
=
[
1
1
1
0
]
n
\left[ \begin{matrix} F_{n+1} & F_{n}\\ F_{n} & F_{n-1} \end{matrix} \right]= \left[ \begin{matrix} 1&1\\ 1&0\\ \end{matrix} \right]^n
[Fn+1FnFnFn−1]=[1110]n
Given an integer
n
n
n, your goal is to compute the last 4 digits of
F
n
Fn
Fn.
Input
The input test file will contain multiple test cases. Each test case consists of a single line containing n (where $0 ≤ n n 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 F n Fn Fn. If the last four digits of F n Fn 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
[
a
11
a
12
a
21
a
22
]
[
b
11
b
12
b
21
b
22
]
=
[
a
11
b
11
+
a
12
b
12
a
11
b
12
+
a
12
b
22
a
21
b
11
+
a
22
b
21
a
21
b
12
+
a
22
b
22
]
\left[ \begin{matrix} a_{11} & a_{12}\\ a_{21} & a_{22} \end{matrix} \right]\left[ \begin{matrix} b_{11} & b_{12}\\ b_{21} & b_{22} \end{matrix} \right]= \left[ \begin{matrix} a_{11}b_{11}+a_{12}b_{12} & a_{11}b_{12}+a_{12}b_{22}\\ a_{21}b_{11}+a_{22}b_{21} & a_{21}b_{12}+a_{22}b_{22}\\ \end{matrix} \right]
[a11a21a12a22][b11b21b12b22]=[a11b11+a12b12a21b11+a22b21a11b12+a12b22a21b12+a22b22]
Also, note that raising any 2 × 2 matrix to the 0th power gives the identity matrix:
[
a
11
a
12
a
21
a
22
]
0
=
[
1
0
0
1
]
\left[ \begin{matrix} a_{11} & a_{12}\\ a_{21} & a_{22}\\ \end{matrix} \right]^{0}=\left[ \begin{matrix} 1 & 0\\ 0 & 1\\ \end{matrix} \right]
[a11a21a12a22]0=[1001]
递推式: f ( n ) = a f ( n − 1 ) + b f ( n − 2 ) f(n) = af(n-1)+bf(n-2) f(n)=af(n−1)+bf(n−2)
[ f ( n + 1 ) f ( n ) ] = [ a b 1 0 ] ∗ [ f ( n ) f ( n − 1 ) ] = [ a b 1 0 ] n − 1 ∗ [ f ( 2 ) f ( 1 ) ] \left[ \begin{matrix} f(n+1)\\ f(n)\\ \end{matrix} \right]= \left[ \begin{matrix} a & b\\ 1 & 0\\ \end{matrix} \right]* \left[ \begin{matrix} f(n)\\ f(n-1)\\ \end{matrix} \right]= \left[ \begin{matrix} a & b\\ 1 & 0\\ \end{matrix} \right]^{n-1} * \left[ \begin{matrix} f(2)\\ f(1)\\ \end{matrix} \right] [f(n+1)f(n)]=[a1b0]∗[f(n)f(n−1)]=[a1b0]n−1∗[f(2)f(1)]
本题的a=b=1
根据快速幂 求出矩阵的n-1次方 A = [ a b 1 0 ] n − 1 A=\left[\begin{matrix}a&b\\1&0\end{matrix}\right]^{n-1} A=[a1b0]n−1
那么 f n = A [ 1 ] [ 0 ] ∗ f 2 + A [ 1 ] [ 1 ] ∗ f 1 f_n = A[1][0] * f_2 + A[1][1]*f_1 fn=A[1][0]∗f2+A[1][1]∗f1
#include <bits/stdc++.h>
using namespace std;
const int N = 105;
int n;//矩阵维数
int mod; //模数
struct mat{
int m[N][N];
mat(){
memset(m,0,sizeof(m));
for(int i=0;i<N;i++){
m[i][i]=1; //初始化单位矩阵
}
}
//矩阵乘法
mat operator*(mat& a) {
mat res;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
res.m[i][j]=0;
for(int k=0;k<n;k++)
res.m[i][j] += m[i][k] * a.m[k][j];
res.m[i][j] %= mod;
}
return res;
}
};
mat fastPow(mat a,int k){ //矩阵快速幂 ★★★★
mat res;
while(k){
if(k&1) res = res * a;
a = a*a;
k>>=1;
}
return res;
}
int main()
{
n=2;
mod = 10000;
mat res,a;
res.m[0][0] = 1;
res.m[0][1] = 1;
res.m[1][0] = 1;
res.m[1][1] = 0;
int input;
while(cin>>input && input != -1){
if(input <= 0){
cout<<0<<endl;
continue;
}
a = fastPow(res,input-1);
cout<<(a.m[1][0]+a.m[1][1])%mod<<endl;
}
return 0;
}