思路:
我们考虑构造转移矩阵
f[1]的指数每次都乘以b[k],f[2]的指数每次都乘以b[k-1]+原来的,以此类推
于是我们可以这样构造
0 0 0 0 …… 0 b[k]
1 0 0 0 …… 0 b[k-1]
0 1 0 0 …… 0 b[k-2]
……
0 0 0 0…… 1 b[1]
c o d e code code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
#define mo 998244352
#define ll long long
using namespace std;
ll mod = 998244353;
ll n, k;
ll f[210], c[210][210];
struct matrix
{
ll a[210][210];
matrix() { memset(a, 0, sizeof(a)); }
}A;
matrix ans;
matrix operator *(const matrix &x,const matrix &y)
{
matrix z;
for(register int i = 0; i < k; i ++)
for(register int j = 0; j < k; j ++)
for(register int t = 0; t < k; t ++)
z.a[i][j] = (z.a[i][j] + x.a[i][t] * y.a[t][j] % mo) % mo;
return z;
}
inline matrix qpow(ll x) {
ans = A;
for(; x; A = A * A, x >>= 1)
if(x & 1) ans = ans * A;
return ans;
}
ll qpow2(ll x, ll k) {
ll ans = 1;
while(k) {
if(k & 1) ans= ans * x % mod;
x = x * x % mod;
k >>= 1;
}
return ans;
}
int main() {
freopen("seq.in", "r", stdin);
freopen("seq.out", "w", stdout);
scanf("%lld%lld", &n, &k);
for(ll i = k - 1; i >= 0; i --)
scanf("%lld", &A.a[i][k - 1]);
for(ll i = 1; i < k; i ++) A.a[i][i - 1] = 1;
for(ll i = 0; i < k; i ++) scanf("%lld", &f[i]);
if(n <= k) {
printf("%lld", f[n - 1]);
return 0;
}
n -= k;
ans = qpow(n - 1);
ll sum = 1;
for(ll i = 0; i < k; i ++)
sum = sum * qpow2(f[i], ans.a[i][k - 1]) % mod;
printf("%lld", sum);
return 0;
}