矩阵快速幂

来源:互联网 发布:管家婆数据库安装 编辑:程序博客网 时间:2024/05/24 05:37

题目描述

存在如下递推式:
F(n+1)=A1*F(n)+A2*F(n-1)+...+An*F(1)
求第K项的值对1000000007取模的结果

输入

单组测试数据

第一行输入两个整数 n , k (1<=n<=100,n<k<=10000000000)

第二行输入 n 个整数 F(1)   F(2)   ...   F(n)

第三行输入 n 个整数A1   A2   ...   An 

输出

输出一个整数

样例输入

2   31   23   4

样例输出

10

题目链接:一道简单的递推题 


很容易就发现这是一个矩阵快速幂,只要能构造出 N*N 的初始矩阵就可以。



代码如下:
#include<iostream>#include<cstring>#include <cstdio>#define LL long longusing namespace std;const int N=105;const LL m=1000000007;int n;LL k;struct Matrix{    LL mp[N][N];};Matrix matrix,A;   // A矩阵存储结果F[1..n] ,matrix存放系数a[1...n]LL f[N];void Initiate(){    for(int i=0; i<n; i++)        scanf("%lld",&matrix.mp[0][i]);    for(int i=1; i<n; i++)    {        for(int j=0; j<n; j++)        {            if(i==(j+1)) matrix.mp[i][j]=1;            else matrix.mp[i][j]=0;        }    }}Matrix Mul(Matrix a,Matrix b){    Matrix c;    memset(c.mp,0,sizeof(c.mp));    for(int k=0; k<n; ++k)    {        for(int i=0; i<n; ++i)        {            if(a.mp[i][k]==0) continue;   //这里进行优化,可以节省时间(卡时间的题)            for(int j=0; j<n; ++j)                c.mp[i][j]=(c.mp[i][j]+(a.mp[i][k]*b.mp[k][j])%m)%m;        }    }    return c;}LL Pow(LL k){    while(k>0)  //这里一定要加上 >0 的条件,否则很容易死循环    {        if(k&1) A=Mul(matrix,A);        k >>= 1;        matrix=Mul(matrix,matrix);    }    return A.mp[0][0];}int main(){//    freopen("in.txt","r",stdin);    while(scanf("%d%lld",&n,&k)!=EOF)    {        for(int i=0; i<n; ++i)            for(int j=0; j<n; ++j)            {                if(i==j) A.mp[i][j]=1;                else A.mp[i][j]=0;            }        for(int i=0; i<n; ++i)      // 把初始的数字 A[1] - A[n] 放入储存结果的矩阵            scanf("%lld",&A.mp[n-i-1][0]);        Initiate();        cout<<Pow(k-n)<<endl;    }    return 0;}