牛客第一场J题让我明白了自己有多少东西都还不会,今天来学习一下神(jian)奇(dan)的矩阵快速幂并如何利用矩阵快速幂求斐波那契数列第n项(n>1e10)
矩阵快速幂(斐波那契数列)
代码:
#include <iostream>
#include <cstring>
#include <string>
#define ll long long
#define mod 1000000007
using namespace std;
struct node {
ll a[2][2];
void init_1() //1 1
{ //0 0
a[0][0] = a[0][1] = 1;
a[1][0] = a[1][1] = 0;
}
void init_2() //1 1
{ //1 0
a[0][0] = a[0][1] = a[1][0] = 1;
a[1][1] = 0;
}
void init_3() //1 0
{ //0 1
a[0][0] = a[1][1] = 1;
a[0][1] = a[1][0] = 0;
}
friend ll getfabo(node a,node b,ll n)
{
if (n == 1)
return 1;
a.init_1();
b.init_2();
b = qmul(b,n-2);
a = mul(a, b);
return a.a[0][0];
}
friend node mul(node a,node b)//朴实无华的矩阵乘法
{
node ans;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
ans.a[i][j] = 0;
for (int k = 0; k < 2; k++)
{
ans.a[i][j] = (ans.a[i][j] + (a.a[i][k] * b.a[k][j] % mod)) % mod;
}
}
}
return ans;
}
friend node qmul(node a, ll n)//(神奇而简单的矩阵快速幂)和快速幂原理一样
{
node b;
b.init_3();
while (n)
{
if (n & 1)
b = mul(a, b);
n >>= 1;
a = mul(a, a);
}
return b;
}
}fabo1,fabo2;
int main()
{
cout << getfabo(fabo1, fabo2, 1000000000000)<<endl;
return 0;
}
证明:
以上就是矩阵快速幂&斐波那契第n项的板子…