【luogu_U145243】斐波那契数列的和

斐波那契数列的和

题目链接:斐波那契数列的和


解题思路

首先数据范围要求我们用矩阵乘法
设: ∣ f n − 2 f n − 1 s n − 2 ∣ \begin{vmatrix}f_{n-2}&f_{n-1}&s_{n-2}\end{vmatrix} fn2fn1sn2
得转移矩阵:
∣ 0 1 0 1 1 1 0 0 1 ∣ \begin{vmatrix}0&1&0\\1&1&1\\0&0&1\end{vmatrix} 010110011

code

#include<iostream>
#include<cstdio>
#include<cstring>
#define myc using
#define ak namespace
#define ioi std
#define int long long

myc ak ioi;

const int mod=1e9+7;

int n;
int a[4][4]={
    
    {
    
    },{
    
    0,0,1,0},{
    
    0,1,1,1},{
    
    0,0,0,1}};
int ans[4][4];
int t[4][4];

void add()
{
    
    
	memset(t,0,sizeof(t));
	for(int i=1;i<=3;i++)
		for(int j=1;j<=3;j++)
			for(int k=1;k<=3;k++)
				t[i][j]=(t[i][j]+ans[i][k]*a[k][j]%mod)%mod;
	for(int i=1;i<=3;i++)
		for(int j=1;j<=3;j++)
			ans[i][j]=t[i][j];
}

void cf()
{
    
    
	memset(t,0,sizeof(t));
	for(int i=1;i<=3;i++)
		for(int j=1;j<=3;j++)
			for(int k=1;k<=3;k++)
				t[i][j]=(t[i][j]+a[i][k]*a[k][j]%mod)%mod;
	for(int i=1;i<=3;i++)
		for(int j=1;j<=3;j++)
			a[i][j]=t[i][j];
}

void ksm(int b)
{
    
    
	ans[1][1]=ans[2][2]=ans[3][3]=1;
	while(b)
	{
    
    
		if(b&1)
			add();
		cf();
		b>>=1;
	}
}

signed main()
{
    
    
	cin>>n;
	if(n==1||n==2)
	{
    
    
		cout<<1<<endl;
		return 0;
	}
	ksm(n-1);
	cout<<(ans[1][3]+ans[2][3]+ans[3][3])%mod<<endl;
}

猜你喜欢

转载自blog.csdn.net/SSL_guyixin/article/details/111400069