矩阵快速幂(洛谷P1962 斐波那契数列 )

#include <bits/stdc++.h>
using namespace std ;
#define ll long long 
ll n ;
const ll mod = 1e9 + 7 ;
struct Matrix
{
	int n, m ;
	ll mp[4][4] ;
	Matrix (){memset(mp, 0, sizeof(mp)) ;} ;
	Matrix operator * (const Matrix & x) const
	{
		Matrix ans ;
		ans.n = n, ans.m = x.m ;
		for(ll i = 1; i <= n; i ++)
		{
			for(ll j = 1; j <= x.m; j ++)
			{
				for(ll k = 1; k <= m; k ++)
				{
					ans.mp[i][j] = (ans.mp[i][j] + mp[i][k] * x.mp[k][j] % mod) % mod ;
				
				}
			}
		}
		return ans ;
	}
} ;
Matrix Quick(Matrix a, ll b)
{
	Matrix res ;
	res.n = a.n, res.m = a.m ;
	for(int i = 1; i <= a.n; i ++)
	{
		res.mp[i][i] = 1 ;
	}
	while(b > 0)
	{
		if(b & (ll)1) res = res * a ;
		a = a * a ;
		b >>= 1 ;
	}
	return res ;
}
int main()
{
	scanf("%lld", &n) ;
	if(n == 1 || n == 2)
	{
		printf("%lld", (ll)1 % mod) ;
		return 0 ;
	} 
	Matrix a, b ;
	a.n = 1, a.m = 2, a.mp[1][1] = a.mp[1][2] = 1 ;
	b.n = 2, b.m = 2, b.mp[1][1] = 0, b.mp[1][2] = 1 ;
	b.mp[2][1] = b.mp[2][2] = 1 ;
	a = a * Quick(b, n - 2) ;
	printf("%lld", a.mp[1][2]) ;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值