P1962 斐波那契数列(矩阵加速)

传送门

思路:很显然,转移矩阵为 [ 1 , 1 1 , 0 ] \begin{bmatrix}1,1\\1,0\end{bmatrix} [1,11,0]

[ F n F n − 1 ] = [ 1 , 1 1 , 0 ] n − 2 .     [ F 2 F 1 ] ( n > 2 ) \begin{bmatrix}F_n\\F_{n-1}\end{bmatrix}=\begin{bmatrix}1,1\\1,0\end{bmatrix}^{n-2}.\ \ \ \begin{bmatrix}F_2\\F_1\end{bmatrix}\quad (n>2) [FnFn1]=[1,11,0]n2.   [F2F1](n>2)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e2+10,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
ll n;
struct Mat{
	ll a[3][3];
	Mat operator * (const Mat & mat)const{ //重载乘号 
		Mat ans;
		memset(ans.a,0,sizeof ans.a);//初始化 
		for(int i=1;i<=2;i++)
			for(int j=1;j<=2;j++)
				for(int k=1;k<=2;k++)
					ans.a[i][j]=(ans.a[i][j]+a[i][k]*mat.a[k][j]%mod)%mod;
		return ans; 
	}
}m;
Mat ksm(Mat m,ll x){ //矩阵快速幂板子 
	 Mat ans;
	 memset(ans.a,0,sizeof ans.a); 
	 ans.a[1][1]=ans.a[2][2]=1; 
	 while(x){
	 	 if(x&1) ans=ans*m;
	 	 m=m*m;
	 	 x>>=1;
	 }
	 return ans;
}
int main(){
	scanf("%lld",&n);
	if(n<=2) puts("1");
	else{
	memset(m.a,0,sizeof m.a);
	m.a[1][1]=m.a[1][2]=m.a[2][1]=1;
	m=ksm(m,n-2);
	printf("%lld\n",(m.a[1][1]+m.a[1][2])%mod);
	}
	return 0;
}