【矩陣乘法】Fibonacci第n項

題目描述

大家都知道Fibonacci數列吧,f[1]=1,f[2]=1,f[3]=2,f[4]=3.......也就是f[n]=f[n-1]+f[n-2]。現在,問題很簡單,輸入n和m,求第n項取模m。

輸入

輸入n,m。

1<=n<=2 000 000 000 。

1<=m<=1 000 000 010 。

輸出

輸出第n項取模m

樣例輸入

5 1000

樣例輸出

5

題解

這題是因爲數據量很大,到了後面數組就沒有辦法保存斐波那契數了

因爲f[i]=f[i-1]+f[i-2]f[i-1]=f[i-1],所以f[i]=1*f[i-1]+1*f[i-2] ,f[i-1]=1*f[i-1]+0*f[i-2],矩陣形式就是

然後遞推,簡化之後

所以f[i]就對應着最後結果的1*2矩陣的上面那個數。然後程序中的mul函數對應的是求的部分,f[2],f[1]都=1,所以(f[2],f[1])T用結構體start來表示,然後就是正常的乘啦,然後取模的時候可以用到快速冪。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
#define ll long long 
ll n,mod;
struct mat
{
	ll x[3][3];
	mat()//構造函數初始化數組
	{
		memset(x,0,sizeof(x));
	}
};
mat model;
mat mul(mat a,mat b)
{
	mat c;
	for(int i=1;i<=2;i++)
		for(int j=1;j<=2;j++)
			for(int k=1;k<=2;k++)
			{
				c.x[i][j]+=a.x[i][k]*b.x[k][j];
				c.x[i][j]%=mod;
			}
	return c;
}
mat mul1(mat a,mat b,int n,int m,int p)
{
	mat c;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=p;j++)
			for(int k=1;k<=m;k++)
			{
				c.x[i][j]+=a.x[i][k]*b.x[k][j];
				c.x[i][j]%=mod;
			}
	return c;
}
mat mi(int n)//快速冪
{
	if(n==1)
		return model;
	mat t=mi(n/2);
	if(n%2==1)
		return mul(mul(t,t),model);
	else
		return mul(t,t);
}
int main()
{
	cin>>n>>mod;
	model.x[1][1]=1;
	model.x[1][2]=1;
	model.x[2][1]=1;
	mat result,start;
	start.x[1][1]=1;//斐波那契的第1、2項都是1
	start.x[2][1]=1;
	result=mul1(mi(n-2),start,2,2,1);//2*2大小的矩陣和2*1大小的矩陣
	cout<<result.x[1][1]%mod;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章