【题目链接】
【算法】
矩阵乘法优化递推
由于本博客不支持数学公式,所以不能将矩阵画出来,请谅解!
【代码】
#include<bits/stdc++.h> using namespace std; #define MAXK 18 struct Matrix { long long mat[MAXK][MAXK]; }; int i,k; long long n,m,p,sum; long long b[MAXK],c[MAXK]; template <typename T> inline void read(T &x) { long long f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; } for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0'; x *= f; } template <typename T> inline void write(T x) { if (x < 0) { putchar('-'); x = -x; } if (x > 9) write(x/10); putchar(x%10+'0'); } template <typename T> inline void writeln(T x) { write(x); puts(""); } inline void multipy(Matrix &a,Matrix b) { int i,j,t; Matrix ans; memset(ans.mat,0,sizeof(ans.mat)); for (i = 1; i <= k + 1; i++) { for (j = 1; j <= k + 1; j++) { for (t = 1; t <= k + 1; t++) { ans.mat[i][j] = (ans.mat[i][j] + a.mat[i][t] * b.mat[t][j]) % p; } } } a = ans; } inline long long solve(long long n) { Matrix a,res; int i,j; long long ans = 0; memset(a.mat,0,sizeof(a.mat)); for (i = 2; i <= k + 1; i++) a.mat[1][i] = a.mat[2][i] = c[i-1]; for (i = 3; i <= k + 1; i++) a.mat[i][i-1] = 1; a.mat[1][1] = 1; memset(res.mat,0,sizeof(res.mat)); for (i = 1; i <= k + 1; i++) res.mat[i][i] = 1; while (n > 0) { if (n & 1) multipy(res,a); multipy(a,a); n >>= 1; } ans = sum; for (i = 2; i <= k + 1; i++) ans = (ans + res.mat[1][i] * b[k-i+2]) % p; return ans; } inline long long query(long long n) { int i; long long ans = 0; if (n <= k) { for (i = 1; i <= n; i++) ans = (ans + b[i]) % p; return ans; } else return solve(n-k); } int main() { read(k); for (i = 1; i <= k; i++) read(b[i]); for (i = 1; i <= k; i++) read(c[i]); read(m); read(n); read(p); for (i = 1; i <= k; i++) sum = (sum + b[i]) % p; writeln((query(n) - query(m-1) + p) % p); return 0; }