code vs 1732 Fibonacci数列 2

1732 Fibonacci数列 2

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 钻石 Diamond
题目描述 Description

在“1250 Fibonacci数列”中,我们求出了第n个Fibonacci数列的值。但是1250中,n<=109。现在,你的任务仍然是求出第n个Fibonacci数列的值,但是注意:n为整数,且1 <= n <= 100000000000000

输入描述 Input Description

输入有多组数据,每组数据占一行,为一个整数n(1 <= n <= 100000000000000)

输出描述 Output Description

输出若干行。每行输出第(对应的输入的)n个Fibonacci数(考虑到数会很大,mod 1000000007)

样例输入 Sample Input

3
4
5

 

样例输出 Sample Output

2
3
5

 

数据范围及提示 Data Size & Hint

1 <= n <= 100000000000000


题解:矩阵加速线性递推

关键在于构造矩阵,初始矩阵中存储的是数列的第0项和第1项

s={0

     1}

然后是加速矩阵

e={0 1

     1  1}

然后先进行矩阵快速幂,再将快速幂后的矩阵乘初始矩阵即为答案

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
long long x,i,j;
int n;
const int  inf= 1000000007;
struct data
{
  long long m[5][5];
};data e,s;
void init(data &a,data b)
{
	for (int  i=1;i<=n;i++)
	 for (int j=1;j<=n;j++)
	  a.m[i][j]=b.m[i][j];
}
data mul(data a,data b)
{
	data c;
	for (int i=1;i<=n;i++)
	 for (int j=1;j<=n;j++)
	  {
	  	c.m[i][j]=0;
	  	for (int k=1;k<=n;k++)
	  	 c.m[i][j]=(long long)(c.m[i][j]%inf+(a.m[i][k]%inf*b.m[k][j]%inf)%inf)%inf;
	  }
	return c;
}
data quickpow(long long  x)
{
	data ans;
	for (i=1;i<=n;i++)
	 for (j=1;j<=n;j++)
	  ans.m[i][j]=0;
	for (int i=1;i<=2;i++)
	 ans.m[i][i]=1;
	data a;
	init(a,e);
	while (x>0)
	 {
	 	if (x&1)
	 	 ans=mul(ans,a);
	 	x=x>>1;
	 	a=mul(a,a);
	 }
	return ans; 
}
int main()
{
  s.m[1][1]=0;
  s.m[2][1]=1;
  e.m[1][1]=0; e.m[1][2]=1; e.m[2][1]=1; e.m[2][2]=1;
  n=2;
  while (scanf("%lld",&x)!=EOF)
   {
   	 data k=quickpow(x-1);
   	 /*for (int i=1;i<=n;i++)
   	  {
   	  	for (int j=1;j<=n;j++)
   	  	 cout<<k.m[i][j]<<" ";
   	  	cout<<endl;
   	  }*/
   	 data l=mul(k,s);
   	 printf("%d\n",l.m[2][1]);
   } 
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值