UVA - 10870 Recurrences (矩阵快速幂)

来源:互联网 发布:adidas跑鞋系列 知乎 编辑:程序博客网 时间:2024/05/29 18:59

Recurrences
Time Limit: 3000MS  64bit IO Format: %lld & %llu

Submit Status uDebug

Description

Download as PDF

题意:

考虑线性递推关系f(n)=a1*f(n-1)+a2*f(n-2)+a3*f(n-3)+...+ad*f(n-d),给你三个整数n,m,d 与数组a与f,让你计算f(n)%m。

分析:矩阵快速幂模板题。


#include <algorithm>#include <iostream>#include <sstream>#include <cstring>#include <cstdlib>#include <string>#include <vector>#include <cstdio>#include <cmath>#include <queue>#include <stack>#include <map>#include <set>using namespace std;#define INF 0x3f3f3f3fconst long long N=1e5+5;long long mod=1e9;const double PI=acos(-1.0);typedef long long ll;typedef struct {    int mat[16][16];}Mat;int n,d,m;Mat multi(Mat a,Mat b) {    Mat c;    memset(c.mat, 0, sizeof(c.mat));    for (int i=1; i<=d; i++) {        for (int j=1; j<=d; j++) {            for (int k=1; k<=d; k++) {                c.mat[i][j]=(c.mat[i][j]+a.mat[i][k]*b.mat[k][j])%mod;            }        }    }    return c;}Mat qui(Mat a,ll b) {    Mat c;    memset(c.mat, 0, sizeof(c.mat));    for (int i=1; i<=d; i++) {        c.mat[i][i]=1;    }    while (b) {        if (b&1) {            c=multi(c, a);        }        a=multi(a, a);        b>>=1;    }    return c;}int main() {    int a[16],f[16];    Mat A;    while (cin>>d>>n>>m&&d) {        mod=m;        for (int i=1; i<=d; i++) {            scanf("%d",&a[i]);            a[i]%=mod;        }        for (int i=1; i<=d; i++) {            scanf("%d",&f[i]);            f[i]%=mod;        }        if (n<=d) {            printf("%d\n",f[n]);            continue;        }                memset(A.mat, 0, sizeof(A.mat));        for (int i=2; i<=d; i++) {            A.mat[i-1][i]=1;        }        for (int i=1; i<=d; i++) {            A.mat[d][i]=a[d-i+1];        }        A=qui(A, n-1);        ll ans=0;        for (int i=1; i<=d; i++) {            ans+=f[i]*A.mat[1][i];            ans%=mod;        }        cout<<ans<<endl;    }    return 0;}


0 0
原创粉丝点击