您的位置:首页 > 其它

【BZOJ1009】【HNOI2008】GT考试

2018-02-18 16:25 453 查看
【题目链接】
点击打开链接

【思路要点】
先用KMP(或者暴力)求出匹配了\(i\)位后出现一个字母\(c\),最大能匹配多少位。
然后矩阵乘法优化DP即可。
时间复杂度\(O(M^3LogN)\)。
【代码】
#include<bits/stdc++.h>
using namespace std;
#define MAXLOG	31
#define MAXN	55
template <typename T> void read(T &x) {
x = 0; int f = 1;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
x *= f;
}
int n, m, P, nxt[MAXN];
int matrix[MAXLOG][MAXN][MAXN];
int vec[1][MAXN], tmp[1][MAXN];
char s[MAXN];
int main() {
read(n), read(m), read(P);
scanf("\n%s", s + 1);
for (int i = 2; i <= m; i++) {
int j = nxt[i - 1];
while (j && s[i] != s[j + 1]) j = nxt[j];
if (s[i] == s[j + 1]) j++;
nxt[i] = j;
}
for (int i = 0; i <= m - 1; i++) {
for (int c = '0'; c <= '9'; c++) {
int j = i;
while (j && c != s[j + 1]) j = nxt[j];
if (c == s[j + 1]) j++;
matrix[0][i][j]++;
}
}
for (int p = 1; p < MAXLOG; p++)
for (int i = 0; i <= m; i++)
for (int j = 0; j <= m; j++)
for (int k = 0; k <= m; k++) {
matrix[p][i][j] += matrix[p - 1][i][k] * matrix[p - 1][k][j];
matrix[p][i][j] %= P;
}
vec[0][0] = 1;
for (int p = 0; p < MAXLOG; p++) {
if ((n & (1 << p)) == 0) continue;
memset(tmp, 0, sizeof(tmp));
for (int i = 0; i <= 0; i++)
for (int j = 0; j <= m; j++)
for (int k = 0; k <= m; k++) {
tmp[i][j] += vec[i][k] * matrix[p][k][j];
tmp[i][j] %= P;
}
for (int i = 0; i <= m; i++)
vec[0][i] = tmp[0][i];
}
int ans = 0;
for (int i = 0; i < m; i++)
ans += vec[0][i];
cout << ans % P << endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: