欢迎大家访问我的老师的OJ———caioj.cn
题面描述
思路
通过矩阵乘法加速,
设
F
(
0
)
=
[
F
i
b
0
=
0
,
F
i
b
1
=
1
]
,
A
=
[
0
1
1
1
]
F(0)=\begin{bmatrix}Fib_0=0,Fib_1=1\end{bmatrix},A=\begin{bmatrix}0&1\\1&1\end{bmatrix}
F(0)=[Fib0=0,Fib1=1],A=[0111]
F ( 1 ) = F ( 0 ) ∗ A = [ F i b 0 ∗ 0 + F i b 1 ∗ 1 = F i b 1 , F i b 0 ∗ 1 + F i b 1 ∗ 1 = F i b 2 ] F(1)=F(0)*A=\begin{bmatrix}Fib_0*0+Fib_1*1=Fib_1,Fib_0*1+Fib_1*1=Fib_2\end{bmatrix} F(1)=F(0)∗A=[Fib0∗0+Fib1∗1=Fib1,Fib0∗1+Fib1∗1=Fib2]
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .................................... ....................................
F ( n ) = F ( n − 1 ) ∗ A = [ F i b n , F i b n + 1 ] F(n)=F(n-1)*A=\begin{bmatrix}Fib_n,Fib_{n+1}\end{bmatrix} F(n)=F(n−1)∗A=[Fibn,Fibn+1]
F ( n ) = F ( n − 2 ) ∗ A 2 F(n)=F(n-2)*A^2 F(n)=F(n−2)∗A2
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .................................... ....................................
F ( n ) = F ( 0 ) ∗ A n F(n)=F(0)*A^n F(n)=F(0)∗An
A n A^n An可用矩阵快速幂 log ( n ) \log(n) log(n)求解。
成功实现加速!
AC code
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<cstring>
#define gc getchar()
using namespace std;
const int mod=10000;
inline void qr(int &x)
{
x=0;int f=1;char c=gc;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc;}
while(c>='0'&&c<='9'){x=x*10+(c^48);c=gc;}
x*=f;
}
void mul(int f[2],int a[2][2])
{
int c[2];memset(c,0,sizeof(c));
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
c[j]=(c[j]+f[k]*a[k][j])%mod;
memcpy(f,c,sizeof(c));
}
void muls(int a[2][2])
{
int c[2][2];memset(c,0,sizeof(c));
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
c[i][j]=(c[i][j]+a[i][k]*a[k][j])%mod;
memcpy(a,c,sizeof(c));
}
int main()
{
int n;
while(qr(n),n!=-1)
{
int f[2]={0,1};
int a[2][2]={{0,1},{1,1}};
while(n)
{
if(n&1)mul(f,a);
n>>=1;muls(a);
}
printf("%d\n",f[0]);
}
return 0;
}