滚动数组写矩阵快速幂

来源:互联网 发布:ubuntu ufw iptables 编辑:程序博客网 时间:2024/06/05 06:24


打了一场比赛,这个比赛中的快速幂的矩阵大小为100* 100,如果朴素地写矩阵快速幂的话,每次进行矩阵相乘的时候是10^6,超时了一下午。

后面才之大滚动数组这个东西,与朴素的不同的就是当前边的矩阵为0的时候,后面的就不用乘了,适用于很多零的情况,部分n^2,部分n^3.


问题 F: 一道简单的递推题

时间限制: 1 Sec  内存限制: 128 MB
提交: 764  解决: 99
[提交][状态][讨论版]

题目描述

存在如下递推式:
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
#include<bits/stdc++.h>using namespace std;typedef long long ll;#define clr(x,y) memset(x,y,sizeof(x))const int maxn = 100 + 10;struct Matrix{    Matrix()    {        clr(a,0);    }    ll a[maxn][maxn];};ll n,m;Matrix Mul(Matrix a,Matrix b,ll mod_val){    Matrix c;    for(int i = 0; i < n; i ++)    {        for(int k = 0; k < n; k ++)        {            if(a.a[i][k] == 0 )                continue;            for(int j = 0; j < n; j ++)            {                c.a[i][j] = (c.a[i][j] + a.a[i][k] * b.a[k][j] % mod_val) % mod_val;            }        }    }    return c;}Matrix pow_mod(Matrix p,ll k,ll mod_val){    Matrix ret;    for(int i = 0; i < n; i ++)        ret.a[i][i] = 1;    while(k)    {        if(k & 1)            ret = Mul(ret,p,mod_val);        k >>= 1;        p = Mul(p,p,mod_val);    }    return ret;}ll a[maxn],b[maxn];int main(){    ll Mod = 1e9 + 7;    while( cin >> n >> m)    {        for(int i = 1; i <= n; i ++)            cin >> a[i],a[i] %= Mod;        for(int i = 1; i <= n; i ++)            cin >> b[i],b[i] %= Mod;        Matrix p;        for(int j = 0; j < n; j ++)            p.a[0][j] = b[j + 1];        for(int i = 1; i < n; i ++)            p.a[i][i - 1] = 1;        Matrix t = pow_mod(p,m - n,Mod);        ll ans = 0;        for(int i = 0; i < n; i ++)        {            ans = (ans + t.a[0][i] * a[n - i] % Mod) % Mod;        }        cout << ans << endl;    }    return 0;}


原创粉丝点击