题意
思路
很容易发现 f n f_n fn一定为 f i c i ( 1 ≤ i ≤ k ) f_i^{c_i}(1\leq i \leq k) fici(1≤i≤k)的乘积,我们只用求出 c i c_i ci也就是指数就好了。
用 r e s i res_i resi存下 f i f_i fi时 f 1.. k f_{1..k} f1..k的指数,观察题目易得出转移矩阵。
另外根据费马小定理,指数对 p − 1 p-1 p−1取模。
代码
#include<cstdio>
#include<cstring>
const int p = 998244353;
struct matrix {
int a[201][201];
};
int n, k;
int b[201], f[400001];
matrix ind;
matrix operator *(matrix &a, matrix &b){
matrix c;
memset(c.a, 0, sizeof(c.a));
for (int i = 1; i <= k; i++)
for (int j = 1; j <= k; j++)
for (int l = 1; l <= k; l++)
c.a[i][j] = (c.a[i][j] + (long long)a.a[i][l] * b.a[l][j]) % (p - 1);
return c;
}
int power(int a, int b) {
long long res = 1;
for (; b; b >>= 1) {
if (b & 1) res = res * a % p;
a = (long long)a * a % p;
}
return res;
}
matrix ksm(int index) {
matrix res;
memset(res.a, 0, sizeof(res.a));
for (int i = 1; i <= k; i++)
res.a[i][i] = 1;
for (; index; index >>= 1) {
if (index & 1) res = res * ind;
ind = ind * ind;
}
return res;
}
int main() {
scanf("%d %d", &n, &k);
for (int i = 1; i <= k; i++)
scanf("%d", &b[i]);
for (int i = 1; i <= k; i++)
scanf("%d", &f[i]);
if (n <= k) {
printf("%d", f[n]);
return 0;
}
for (int i = 1; i <= k; i++)
ind.a[i - 1][i] = (i != 1), ind.a[k][i] = b[k - i + 1];
ind = ksm(n - k);
long long ans = 1;
for (int i = 1; i <= k; i++)
ans = ans * power(f[i], ind.a[k][i]) % p;
printf("%d", ans);
}