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}
Xn−1=[Fn−1Fn−2]
X
n
=
[
F
n
F
n
−
1
]
X_{n} = \begin{bmatrix} F_{n}\\ F_{n-1} \end{bmatrix}
Xn=[FnFn−1]
那么我们需要找到的矩阵 A 就满足:
A
⋅
X
n
−
1
=
X
n
A \cdot X_{n-1} = X_{n}
A⋅Xn−1=Xn
又因为:
{
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}
{Fn=Fn−1+Fn−2Fn−1=Fn−1+0⋅Fn−2
所以:
A
=
[
1
,
1
0
,
0
]
A = \begin{bmatrix} 1,1\\ 0,0 \end{bmatrix}
A=[1,10,0]
即:
[
1
,
1
0
,
0
]
\begin{bmatrix} 1,1\\ 0,0 \end{bmatrix}
[1,10,0]
⋅
\cdot
⋅
[
F
n
−
1
F
n
−
2
]
\begin{bmatrix}F_{n-1}\\ F_{n-2} \end{bmatrix}
[Fn−1Fn−2]
=
[
F
n
F
n
−
1
]
= \begin{bmatrix} F_{n}\\ F_{n-1} \end{bmatrix}
=[FnFn−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}
[FnFn−1]=[1,10,0]⋅[Fn−1Fn−2]=[1,10,0]2⋅[Fn−2Fn−3]⋅⋅⋅⋅=[1,10,0]n−1⋅[F1F0]
我们用矩阵快速幂求出
[
1
,
1
0
,
0
]
n
−
1
\begin{bmatrix} 1,1\\ 0,0 \end{bmatrix}^{n-1}
[1,10,0]n−1后,结果矩阵的第一行与上面公式中最后的
[
F
1
F
0
]
\begin{bmatrix}F_{1}\\ F_{0} \end{bmatrix}
[F1F0]做矩阵乘法即是最终结果。
#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}
Xn−1=⎣⎢⎢⎢⎢⎢⎢⎡Fn−1Fn−2i3i2i1⎦⎥⎥⎥⎥⎥⎥⎤
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}
Xn=⎣⎢⎢⎢⎢⎢⎢⎡FnFn−1(i+1)3(i+1)2(i+1)1⎦⎥⎥⎥⎥⎥⎥⎤
A
⋅
X
n
−
1
=
X
n
A \cdot X_{n-1} = X_{n}
A⋅Xn−1=Xn
[
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,XX,X,X,X,X,XX,X,X,X,X,XX,X,X,X,X,XX,X,X,X,X,XX,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}
⎣⎢⎢⎢⎢⎢⎢⎡Fn−1Fn−2(i+1)3(i+1)2i+11⎦⎥⎥⎥⎥⎥⎥⎤
=
[
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}
=⎣⎢⎢⎢⎢⎢⎢⎡FnFn−1i3i2i1⎦⎥⎥⎥⎥⎥⎥⎤
{
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}
⎩⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎧Fn=1⋅Fn−1+1⋅Fn−2+1⋅i3+1⋅i2+1⋅i+1⋅1Fn−1=1⋅Fn−1+0⋅Fn−2+0⋅i3+0⋅i2+0⋅i+0⋅1(i+1)3=0⋅Fn−1+0⋅Fn−2+1⋅i3+3⋅i2+3⋅i+1⋅1(i+1)2=0⋅Fn−1+0⋅Fn−2+0⋅i3+1⋅i2+2⋅i+1⋅1i+1=0⋅Fn−1+0⋅Fn−2+0⋅i3+0⋅i2+1⋅i+1⋅11=0⋅Fn−1+0⋅Fn−2+0⋅i3+0⋅i2+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,11,0,0,0,0,00,0,1,3,3,10,0,0,1,2,10,0,0,0,1,10,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}
⎣⎢⎢⎢⎢⎢⎢⎡FnFn−1(i+1)3(i+1)2i+11⎦⎥⎥⎥⎥⎥⎥⎤=⎣⎢⎢⎢⎢⎢⎢⎡1,1,1,1,1,11,0,0,0,0,00,0,1,3,3,10,0,0,1,2,10,0,0,0,1,10,0,0,0,0,1⎦⎥⎥⎥⎥⎥⎥⎤⋅⎣⎢⎢⎢⎢⎢⎢⎡Fn−1Fn−2i3i2i1⎦⎥⎥⎥⎥⎥⎥⎤=⎣⎢⎢⎢⎢⎢⎢⎡1,1,1,1,1,11,0,0,0,0,00,0,1,3,3,10,0,0,1,2,10,0,0,0,1,10,0,0,0,0,1⎦⎥⎥⎥⎥⎥⎥⎤2⋅⎣⎢⎢⎢⎢⎢⎢⎡Fn−2Fn−3(i−1)3(i−1)2i−11⎦⎥⎥⎥⎥⎥⎥⎤=⋅⋅⋅⋅=⎣⎢⎢⎢⎢⎢⎢⎡1,1,1,1,1,11,0,0,0,0,00,0,1,3,3,10,0,0,1,2,10,0,0,0,1,10,0,0,0,0,1⎦⎥⎥⎥⎥⎥⎥⎤n−1⋅⎣⎢⎢⎢⎢⎢⎢⎡F1F0232221⎦⎥⎥⎥⎥⎥⎥⎤
最后求出
A
n
−
1
A^{n-1}
An−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;
}