矩阵快速幂

题目描述

存在如下递推式:
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   3
1   2
3   4

样例输出

10

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


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



代码如下:
#include<iostream>
#include<cstring>
#include <cstdio>
#define LL long long

using 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;
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值