POJ 3070 Fibonacci
题目链接:http://poj.org/problem?id=3070
题意:求Fn % 1000是多少?(公式题目已给出) 此题的公式就是Fn = Fn-1 + Fn-2 ,我们令:
X
n
−
1
=
[
F
n
−
1
F
n
−
2
]
X_{n-1} = \begin{bmatrix}F_{n-1}\\ F_{n-2} \end{bmatrix}
X n − 1 = [ F n − 1 F n − 2 ]
X
n
=
[
F
n
F
n
−
1
]
X_{n} = \begin{bmatrix} F_{n}\\ F_{n-1} \end{bmatrix}
X n = [ F n F n − 1 ] 那么我们需要找到的矩阵 A 就满足:
A
⋅
X
n
−
1
=
X
n
A \cdot X_{n-1} = X_{n}
A ⋅ X n − 1 = X n 又因为:
{
F
n
=
F
n
−
1
+
F
n
−
2
F
n
−
1
=
F
n
−
1
+
0
⋅
F
n
−
2
\begin{cases} F_{n} = F_{n-1} + F_{n-2}\\ F_{n-1} = F_{n-1} + 0 \cdot F_{n-2} \end{cases}
{ F n = F n − 1 + F n − 2 F n − 1 = F n − 1 + 0 ⋅ F n − 2 所以:
A
=
[
1
,
1
0
,
0
]
A = \begin{bmatrix} 1,1\\ 0,0 \end{bmatrix}
A = [ 1 , 1 0 , 0 ] 即:
[
1
,
1
0
,
0
]
\begin{bmatrix} 1,1\\ 0,0 \end{bmatrix}
[ 1 , 1 0 , 0 ]
⋅
\cdot
⋅
[
F
n
−
1
F
n
−
2
]
\begin{bmatrix}F_{n-1}\\ F_{n-2} \end{bmatrix}
[ F n − 1 F n − 2 ]
=
[
F
n
F
n
−
1
]
= \begin{bmatrix} F_{n}\\ F_{n-1} \end{bmatrix}
= [ F n F n − 1 ] 综上所述:
[
F
n
F
n
−
1
]
=
[
1
,
1
0
,
0
]
⋅
[
F
n
−
1
F
n
−
2
]
=
[
1
,
1
0
,
0
]
2
⋅
[
F
n
−
2
F
n
−
3
]
⋅
⋅
⋅
⋅
=
[
1
,
1
0
,
0
]
n
−
1
⋅
[
F
1
F
0
]
\begin{bmatrix} F_{n}\\ F_{n-1} \end{bmatrix} = \begin{bmatrix} 1,1\\ 0,0 \end{bmatrix} \cdot \begin{bmatrix}F_{n-1}\\ F_{n-2} \end{bmatrix} = \begin{bmatrix} 1,1\\ 0,0 \end{bmatrix}^{2} \cdot \begin{bmatrix}F_{n-2}\\ F_{n-3} \end{bmatrix} \cdot \cdot \cdot \cdot =\begin{bmatrix} 1,1\\ 0,0 \end{bmatrix}^{n-1} \cdot \begin{bmatrix}F_{1}\\ F_{0} \end{bmatrix}
[ F n F n − 1 ] = [ 1 , 1 0 , 0 ] ⋅ [ F n − 1 F n − 2 ] = [ 1 , 1 0 , 0 ] 2 ⋅ [ F n − 2 F n − 3 ] ⋅ ⋅ ⋅ ⋅ = [ 1 , 1 0 , 0 ] n − 1 ⋅ [ F 1 F 0 ] 我们用矩阵快速幂求出
[
1
,
1
0
,
0
]
n
−
1
\begin{bmatrix} 1,1\\ 0,0 \end{bmatrix}^{n-1}
[ 1 , 1 0 , 0 ] n − 1 后,结果矩阵的第一行与上面公式中最后的
[
F
1
F
0
]
\begin{bmatrix}F_{1}\\ F_{0} \end{bmatrix}
[ F 1 F 0 ] 做矩阵乘法即是最终结果。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define mod 10000
using namespace std;
typedef long long LL;
const int Max_n= 100005 ;
struct Mat{
int mat[ 2 ] [ 2 ] ;
} ;
Mat mul ( Mat a, Mat b) {
Mat ans;
for ( int i= 0 ; i< 2 ; i++ ) {
for ( int j= 0 ; j< 2 ; j++ ) {
ans. mat[ i] [ j] = 0 ;
for ( int k= 0 ; k< 2 ; k++ )
ans. mat[ i] [ j] + = ( a. mat[ i] [ k] * b. mat[ k] [ j] ) % mod;
ans. mat[ i] [ j] % = mod;
}
}
return ans;
}
Mat q_pow ( Mat a, int b) {
Mat ans= { 1 , 0 , 0 , 1 } ;
Mat res= a;
while ( b) {
if ( b& 1 ) ans= mul ( ans, res) ;
res= mul ( res, res) ;
b>>= 1 ;
}
return ans;
}
int main ( ) {
int n;
while ( ~ scanf ( "%d" , & n) && n!= - 1 ) {
Mat a= { 1 , 1 , 1 , 0 } ;
Mat ans= { 0 , 0 , 0 , 0 } ;
ans= q_pow ( a, n) ;
printf ( "%d\n" , ans. mat[ 0 ] [ 1 ] ) ;
}
return 0 ;
}
2018年湘潭大学程序设计竞赛 G 又见斐波那契
题目地址:https://ac.nowcoder.com/acm/contest/105/G?&headNav=www&headNav=acm 本题需要注意的点就是矩阵的数据类型,用int中间运算会爆掉,所以构造矩阵的时候需要用 ll 思路:与上面题目套路相同
X
n
−
1
=
[
F
n
−
1
F
n
−
2
i
3
i
2
i
1
]
X_{n-1} = \begin{bmatrix} F_{n-1}\\ F_{n-2} \\ i^{3}\\ i^{2}\\ i\\ 1 \end{bmatrix}
X n − 1 = ⎣ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎡ F n − 1 F n − 2 i 3 i 2 i 1 ⎦ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎤
X
n
=
[
F
n
F
n
−
1
(
i
+
1
)
3
(
i
+
1
)
2
(
i
+
1
)
1
]
X_{n} = \begin{bmatrix} F_{n}\\ F_{n-1} \\ (i+1)^{3}\\ (i+1)^{2}\\ (i+1)\\ 1 \end{bmatrix}
X n = ⎣ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎡ F n F n − 1 ( i + 1 ) 3 ( i + 1 ) 2 ( i + 1 ) 1 ⎦ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎤
A
⋅
X
n
−
1
=
X
n
A \cdot X_{n-1} = X_{n}
A ⋅ X n − 1 = X n
[
X
,
X
,
X
,
X
,
X
,
X
X
,
X
,
X
,
X
,
X
,
X
X
,
X
,
X
,
X
,
X
,
X
X
,
X
,
X
,
X
,
X
,
X
X
,
X
,
X
,
X
,
X
,
X
X
,
X
,
X
,
X
,
X
,
X
]
\begin{bmatrix} X,X,X,X,X,X\\ X,X,X,X,X,X\\ X,X,X,X,X,X\\ X,X,X,X,X,X\\ X,X,X,X,X,X\\ X,X,X,X,X,X \end{bmatrix}
⎣ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎡ X , X , X , X , X , X X , X , X , X , X , X X , X , X , X , X , X X , X , X , X , X , X X , X , X , X , X , X X , X , X , X , X , X ⎦ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎤
⋅
\cdot
⋅
[
F
n
−
1
F
n
−
2
(
i
+
1
)
3
(
i
+
1
)
2
i
+
1
1
]
\begin{bmatrix}F_{n-1}\\ F_{n-2} \\ (i+1)^{3}\\ (i+1)^{2}\\ i+1\\ 1 \end{bmatrix}
⎣ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎡ F n − 1 F n − 2 ( i + 1 ) 3 ( i + 1 ) 2 i + 1 1 ⎦ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎤
=
[
F
n
F
n
−
1
i
3
i
2
i
1
]
= \begin{bmatrix} F_{n}\\ F_{n-1} \\ i^{3}\\ i^{2}\\ i\\ 1 \end{bmatrix}
= ⎣ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎡ F n F n − 1 i 3 i 2 i 1 ⎦ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎤
{
F
n
=
1
⋅
F
n
−
1
+
1
⋅
F
n
−
2
+
1
⋅
i
3
+
1
⋅
i
2
+
1
⋅
i
+
1
⋅
1
F
n
−
1
=
1
⋅
F
n
−
1
+
0
⋅
F
n
−
2
+
0
⋅
i
3
+
0
⋅
i
2
+
0
⋅
i
+
0
⋅
1
(
i
+
1
)
3
=
0
⋅
F
n
−
1
+
0
⋅
F
n
−
2
+
1
⋅
i
3
+
3
⋅
i
2
+
3
⋅
i
+
1
⋅
1
(
i
+
1
)
2
=
0
⋅
F
n
−
1
+
0
⋅
F
n
−
2
+
0
⋅
i
3
+
1
⋅
i
2
+
2
⋅
i
+
1
⋅
1
i
+
1
=
0
⋅
F
n
−
1
+
0
⋅
F
n
−
2
+
0
⋅
i
3
+
0
⋅
i
2
+
1
⋅
i
+
1
⋅
1
1
=
0
⋅
F
n
−
1
+
0
⋅
F
n
−
2
+
0
⋅
i
3
+
0
⋅
i
2
+
0
⋅
i
+
1
⋅
1
\begin{cases} F_{n} = 1 \cdot F_{n-1} + 1 \cdot F_{n-2} + 1 \cdot i^{3} + 1 \cdot i^{2} + 1 \cdot i + 1 \cdot 1\\ F_{n-1} = 1 \cdot F_{n-1} + 0 \cdot F_{n-2} + 0 \cdot i^{3} + 0 \cdot i^{2} + 0 \cdot i + 0 \cdot 1\\ (i+1)^{3} = 0 \cdot F_{n-1} + 0 \cdot F_{n-2} + 1 \cdot i^{3} + 3 \cdot i^{2} + 3 \cdot i + 1 \cdot 1\\ (i+1)^{2} = 0 \cdot F_{n-1} + 0 \cdot F_{n-2} + 0 \cdot i^{3} + 1 \cdot i^{2} + 2 \cdot i + 1 \cdot 1\\ i+1 = 0 \cdot F_{n-1} + 0 \cdot F_{n-2} + 0 \cdot i^{3} + 0 \cdot i^{2} + 1 \cdot i + 1 \cdot 1\\ 1 = 0 \cdot F_{n-1} + 0 \cdot F_{n-2} + 0 \cdot i^{3} + 0 \cdot i^{2} + 0 \cdot i + 1 \cdot 1 \end{cases}
⎩ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎨ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎧ F n = 1 ⋅ F n − 1 + 1 ⋅ F n − 2 + 1 ⋅ i 3 + 1 ⋅ i 2 + 1 ⋅ i + 1 ⋅ 1 F n − 1 = 1 ⋅ F n − 1 + 0 ⋅ F n − 2 + 0 ⋅ i 3 + 0 ⋅ i 2 + 0 ⋅ i + 0 ⋅ 1 ( i + 1 ) 3 = 0 ⋅ F n − 1 + 0 ⋅ F n − 2 + 1 ⋅ i 3 + 3 ⋅ i 2 + 3 ⋅ i + 1 ⋅ 1 ( i + 1 ) 2 = 0 ⋅ F n − 1 + 0 ⋅ F n − 2 + 0 ⋅ i 3 + 1 ⋅ i 2 + 2 ⋅ i + 1 ⋅ 1 i + 1 = 0 ⋅ F n − 1 + 0 ⋅ F n − 2 + 0 ⋅ i 3 + 0 ⋅ i 2 + 1 ⋅ i + 1 ⋅ 1 1 = 0 ⋅ F n − 1 + 0 ⋅ F n − 2 + 0 ⋅ i 3 + 0 ⋅ i 2 + 0 ⋅ i + 1 ⋅ 1
=
>
= >
= >
A
=
[
1
,
1
,
1
,
1
,
1
,
1
1
,
0
,
0
,
0
,
0
,
0
0
,
0
,
1
,
3
,
3
,
1
0
,
0
,
0
,
1
,
2
,
1
0
,
0
,
0
,
0
,
1
,
1
0
,
0
,
0
,
0
,
0
,
1
]
A = \begin{bmatrix} 1,1,1,1,1,1\\ 1,0,0,0,0,0\\ 0,0,1,3,3,1\\ 0,0,0,1,2,1\\ 0,0,0,0,1,1\\ 0,0,0,0,0,1 \end{bmatrix}
A = ⎣ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎡ 1 , 1 , 1 , 1 , 1 , 1 1 , 0 , 0 , 0 , 0 , 0 0 , 0 , 1 , 3 , 3 , 1 0 , 0 , 0 , 1 , 2 , 1 0 , 0 , 0 , 0 , 1 , 1 0 , 0 , 0 , 0 , 0 , 1 ⎦ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎤
[
F
n
F
n
−
1
(
i
+
1
)
3
(
i
+
1
)
2
i
+
1
1
]
=
[
1
,
1
,
1
,
1
,
1
,
1
1
,
0
,
0
,
0
,
0
,
0
0
,
0
,
1
,
3
,
3
,
1
0
,
0
,
0
,
1
,
2
,
1
0
,
0
,
0
,
0
,
1
,
1
0
,
0
,
0
,
0
,
0
,
1
]
⋅
[
F
n
−
1
F
n
−
2
i
3
i
2
i
1
]
=
[
1
,
1
,
1
,
1
,
1
,
1
1
,
0
,
0
,
0
,
0
,
0
0
,
0
,
1
,
3
,
3
,
1
0
,
0
,
0
,
1
,
2
,
1
0
,
0
,
0
,
0
,
1
,
1
0
,
0
,
0
,
0
,
0
,
1
]
2
⋅
[
F
n
−
2
F
n
−
3
(
i
−
1
)
3
(
i
−
1
)
2
i
−
1
1
]
=
⋅
⋅
⋅
⋅
=
[
1
,
1
,
1
,
1
,
1
,
1
1
,
0
,
0
,
0
,
0
,
0
0
,
0
,
1
,
3
,
3
,
1
0
,
0
,
0
,
1
,
2
,
1
0
,
0
,
0
,
0
,
1
,
1
0
,
0
,
0
,
0
,
0
,
1
]
n
−
1
⋅
[
F
1
F
0
2
3
2
2
2
1
]
\begin{bmatrix} F_{n}\\ F_{n-1} \\ (i+1)^{3}\\ (i+1)^{2}\\ i+1\\ 1 \end{bmatrix} = \begin{bmatrix} 1,1,1,1,1,1\\ 1,0,0,0,0,0\\ 0,0,1,3,3,1\\ 0,0,0,1,2,1\\ 0,0,0,0,1,1\\ 0,0,0,0,0,1 \end{bmatrix} \cdot \begin{bmatrix}F_{n-1}\\ F_{n-2} \\ i^{3}\\ i^{2}\\ i\\ 1 \end{bmatrix} = \begin{bmatrix} 1,1,1,1,1,1\\ 1,0,0,0,0,0\\ 0,0,1,3,3,1\\ 0,0,0,1,2,1\\ 0,0,0,0,1,1\\ 0,0,0,0,0,1 \end{bmatrix}^{2} \cdot \begin{bmatrix}F_{n-2}\\ F_{n-3} \\ (i-1)^{3}\\ (i-1)^{2}\\ i-1\\ 1 \end{bmatrix} = \cdot \cdot \cdot \cdot = \begin{bmatrix} 1,1,1,1,1,1\\ 1,0,0,0,0,0\\ 0,0,1,3,3,1\\ 0,0,0,1,2,1\\ 0,0,0,0,1,1\\ 0,0,0,0,0,1 \end{bmatrix}^{n - 1} \cdot \begin{bmatrix}F_{1}\\ F_{0} \\ 2^{3}\\ 2^{2}\\ 2\\ 1 \end{bmatrix}
⎣ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎡ F n F n − 1 ( i + 1 ) 3 ( i + 1 ) 2 i + 1 1 ⎦ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎤ = ⎣ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎡ 1 , 1 , 1 , 1 , 1 , 1 1 , 0 , 0 , 0 , 0 , 0 0 , 0 , 1 , 3 , 3 , 1 0 , 0 , 0 , 1 , 2 , 1 0 , 0 , 0 , 0 , 1 , 1 0 , 0 , 0 , 0 , 0 , 1 ⎦ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎤ ⋅ ⎣ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎡ F n − 1 F n − 2 i 3 i 2 i 1 ⎦ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎤ = ⎣ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎡ 1 , 1 , 1 , 1 , 1 , 1 1 , 0 , 0 , 0 , 0 , 0 0 , 0 , 1 , 3 , 3 , 1 0 , 0 , 0 , 1 , 2 , 1 0 , 0 , 0 , 0 , 1 , 1 0 , 0 , 0 , 0 , 0 , 1 ⎦ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎤ 2 ⋅ ⎣ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎡ F n − 2 F n − 3 ( i − 1 ) 3 ( i − 1 ) 2 i − 1 1 ⎦ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎤ = ⋅ ⋅ ⋅ ⋅ = ⎣ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎡ 1 , 1 , 1 , 1 , 1 , 1 1 , 0 , 0 , 0 , 0 , 0 0 , 0 , 1 , 3 , 3 , 1 0 , 0 , 0 , 1 , 2 , 1 0 , 0 , 0 , 0 , 1 , 1 0 , 0 , 0 , 0 , 0 , 1 ⎦ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎤ n − 1 ⋅ ⎣ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎡ F 1 F 0 2 3 2 2 2 1 ⎦ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎤ 最后求出
A
n
−
1
A^{n-1}
A n − 1 后,与公式中最后的行列式相乘即可。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int mod= 1000000007 ;
const int Max_n= 500005 ;
int x[ 6 ] = { 1 , 0 , 8 , 4 , 2 , 1 } ;
struct Mat{
LL mat[ 6 ] [ 6 ] ;
} ;
Mat mul ( Mat a, Mat b) {
Mat z;
for ( int i= 0 ; i< 6 ; i++ ) {
for ( int j= 0 ; j< 6 ; j++ ) {
z. mat[ i] [ j] = 0 ;
for ( int k= 0 ; k< 6 ; k++ ) {
z. mat[ i] [ j] + = ( a. mat[ i] [ k] * b. mat[ k] [ j] ) % mod;
z. mat[ i] [ j] % = mod;
}
}
}
return z;
}
Mat q_pow ( Mat a, LL b) {
Mat ans= {
1 , 0 , 0 , 0 , 0 , 0 ,
0 , 1 , 0 , 0 , 0 , 0 ,
0 , 0 , 1 , 0 , 0 , 0 ,
0 , 0 , 0 , 1 , 0 , 0 ,
0 , 0 , 0 , 0 , 1 , 0 ,
0 , 0 , 0 , 0 , 0 , 1 ,
} ;
Mat res= a;
while ( b) {
if ( b& 1 ) ans= mul ( ans, res) ;
res= mul ( res, res) ;
b>>= 1 ;
}
return ans;
}
int main ( ) {
Mat a= {
1 , 1 , 1 , 1 , 1 , 1 ,
1 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 1 , 3 , 3 , 1 ,
0 , 0 , 0 , 1 , 2 , 1 ,
0 , 0 , 0 , 0 , 1 , 1 ,
0 , 0 , 0 , 0 , 0 , 1
} ;
int t;
scanf ( "%d" , & t) ;
while ( t-- ) {
LL n;
scanf ( "%lld" , & n) ;
if ( n== 1 ) {
printf ( "1\n" ) ;
continue ;
}
if ( n== 0 ) {
printf ( "0\n" ) ;
continue ;
}
Mat ans= q_pow ( a, n- 1 ) ;
int res= 0 ;
for ( int i= 0 ; i< 6 ; i++ ) {
res+ = ( ans. mat[ 0 ] [ i] * x[ i] ) % mod;
res% = mod;
}
printf ( "%d\n" , res) ;
}
return 0 ;
}