51nod-1242-超大斐波那契(矩阵快速幂)

51nod-1242-网址


斐波那契数列的定义如下:

F(0) = 0
F(1) = 1
F(n) = F(n - 1) + F(n - 2) (n >= 2)

(1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, ...)
给出n,求F(n),由于结果很大,输出F(n) % 1000000009的结果即可。
Input
输入1个数n(1 <= n <= 10^18)。
Output
输出F(n) % 1000000009的结果。
Input示例
11
Output示例
89


1e18!!!!!!不是一般的大,

不过通过这一题学会了矩阵乘法,矩阵快速幂

一个矩阵

f[2][2] =

{

    1 , 1,

    1 , 0,

};

它的(n - 1)次幂后 (n >= 1),f[0][0]就是斐波那契额数列的 第 n 项,

不知道道理,反正就是这个规律~~~~

嗯 这个就当作矩阵快速幂的模板吧

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>

using namespace std;

typedef long long LL;
const int N = 2;
const int Inf = 1000000009;

struct matrix //定义一个 N * N 的矩阵
{
	LL a[N][N];
};

matrix multiply(matrix x,matrix y) // 矩阵乘法 (取模)
{
	matrix res;
	memset(res.a,0,sizeof(res.a));
	for(int i = 0;i < N;i ++)
	{
		for(int j = 0;j < N;j ++)
		{
			for(int k = 0;k < N;k ++)
			{
				res.a[i][j] += (x.a[i][k]%Inf * y.a[k][j]%Inf)% Inf;
				res.a[i][j] %= Inf;
			}
		}
	}
	return res;
}

matrix MFP(matrix a,LL b)
{
	matrix res;
	for(int i = 0;i < N;i ++)
    {
        for(int j = 0;j < N;j ++)
        {
            if(i == j)
                res.a[i][j] = 1;
            else
                res.a[i][j] = 0;
        }
    }

	while(b)
	{
		if(b & 1 == 1LL)
			res = multiply(res,a);
		a = multiply(a,a);
		b >>= 1;
	}
	return res;
}

int main()
{
	matrix f;

	LL n;
	while(cin>>n)
    {
        n --;
        f.a[0][0] = 1;
        f.a[0][1] = 1;
        f.a[1][0] = 1;
        f.a[1][1] = 0;
        if(0 == n)
            cout<<"0"<<endl;
        else
        {
            f = MFP(f,n);
            cout<<f.a[0][0]<<endl;
        }

    }

	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41003528/article/details/80146008
今日推荐