【题目链接】
【算法】
矩阵乘法优化递推
由于本博客不支持数学公式,所以不能将矩阵画出来,请谅解!
【代码】
#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;
}