UVA 10870 Recurrences
矩阵快速幂。
矩阵很容易构造:
#include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<algorithm> using namespace std; int d,n; long long m; long long F[20],D[20]; struct Matrix { long long A[20][20]; int R, C; Matrix operator*(Matrix b); }; Matrix X, Y, Z; Matrix Matrix::operator*(Matrix b) { Matrix c; memset(c.A, 0, sizeof(c.A)); int i, j, k; for (i = 1; i <= R; i++) for (j = 1; j <= C; j++) for (k = 1; k <= C; k++) c.A[i][j] = (c.A[i][j] + (A[i][k] * b.A[k][j])%m)%m; c.R=R; c.C=b.C; return c; } void init() { n = n - 1; memset(X.A,0,sizeof X.A); memset(Y.A,0,sizeof Y.A); memset(Z.A,0,sizeof Z.A); for(int j=1;j<=d;j++) Z.A[1][j]=F[j]; Z.R = 1; Z.C = d; for(int i=1;i<=d;i++) Y.A[i][i]=1; Y.R = d; Y.C = d; for(int j=1;j<=d-1;j++) X.A[j+1][j]=1; for(int i=1;i<=d;i++) X.A[i][d]=D[d-i+1]; X.R = d; X.C = d; } void work() { while (n) { if (n % 2 == 1) Y = Y*X; n = n >> 1; X = X*X; } Z = Z*Y; printf("%lld\n", Z.A[1][1]); } void read() { for(int i=1;i<=d;i++) scanf("%lld",&D[i]); for(int i=1;i<=d;i++) scanf("%lld",&F[i]); } int main() { while(~scanf("%d%d%lld",&d,&n,&m)) { if(d==0&&n==0&&m==0) break; read(); init(); work(); } return 0; }