题解
题解
以准考证号后缀与不吉利数字的最长匹配长度为状态, K M P KMP KMP 预处理处状态转移矩阵,进行矩阵快速幂即可。总时间复杂度为 O ( M 3 log N ) O(M^3\log N) O(M3logN)。
#include <bits/stdc++.h>
using namespace std;
#define rep(i, l, r) for (int i = l, _ = r; i < _; ++i)
const int MAXN = 22;
int N, M, K;
string ban;
struct matrix
{
int n, a[MAXN][MAXN];
matrix() {
n = 0, memset(a, 0, sizeof(a)); }
void operator*=(const matrix &o)
{
int b[MAXN][MAXN];
memset(b, 0, sizeof(b));
rep(i, 0, n) rep(k, 0, n) rep(j, 0, n) b[i][j] = (b[i][j] + a[i][k] * o.a[k][j]) % K;
memcpy(a, b, sizeof(a));
}
} A, res;
int nxt[MAXN];
void kmp(string a, int n, int tran[][MAXN])
{
int i = 0, j = -1;
nxt[i] = j;
while (i < n)
{
while (j >= 0 && a[i] != a[j])
j = nxt[j];
++i, ++j;
nxt[i] = j;
}
rep(k, 0, n) rep(num, 0, 10)
{
i = j = k;
char c = num + '0';
while (j >= 0 && a[j] != c)
j = nxt[j];
++j;
if (j == n)
continue;
++tran[i][j];
}
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> N >> M >> K;
cin >> ban;
A.n = res.n = M;
kmp(ban, M, A.a);
rep(i, 0, res.n) res.a[i][i] = 1;
while (N)
{
if (N & 1)
res *= A;
A *= A, N >>= 1;
}
int sum = 0;
rep(i, 0, res.n) sum = (sum + res.a[0][i]) % K;
cout << sum << '\n';
return 0;
}