Fibonacci[POJ3070]

欢迎大家访问我的老师的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=[Fib00+Fib11=Fib1,Fib01+Fib11=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(n1)A=[Fibn,Fibn+1]

F ( n ) = F ( n − 2 ) ∗ A 2 F(n)=F(n-2)*A^2 F(n)=F(n2)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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值