一直是 80 分,思路就是把转移压缩,不知道错在哪里了,代码应该写的比较清晰,有哪位神仙哥哥可以说一下坑点或 debug 一下吗,感激不尽!
#include <bits/stdc++.h>
using namespace std;
#define il inline
#define re register
#define rep(i, s, e) for (re int i = s; i <= e; ++i)
#define drep(i, s, e) for (re int i = s; i >= e; --i)
#define file(a) freopen(#a".in", "r", stdin), freopen(#a".out", "w", stdout)
const int N = 1000000 + 10;
il int read() {
int x = 0; bool f = true; char c = getchar();
while (!isdigit(c)) {if (c == '-') f = false; c = getchar();}
while (isdigit(c)) x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
return f ? x : -x;
}
int n, m, tot, to[N][26], fail[N], trs[N], dep[N];
bool isfin[N];
il void insert(char *s, int len) {
int u = 0;
for (int i = 1; i <= len; u = to[u][s[i] - 'a'], ++i) {
if (!to[u][s[i] - 'a']) to[u][s[i] - 'a'] = ++tot, dep[tot] = i;
}
isfin[u] = true;
}
il void AC() {
queue <int> q;
rep(i, 0, 25) if (to[0][i]) q.push(to[0][i]), trs[to[0][i]] = isfin[to[0][i]] << 1;
while (q.size()) {
int u = q.front(); q.pop();
rep(i, 0, 25) {
if (to[u][i]) {
fail[to[u][i]] = to[fail[u]][i];
trs[to[u][i]] |= trs[fail[to[u][i]]] | (isfin[to[u][i]] << dep[to[u][i]]);
q.push(to[u][i]);
}
else to[u][i] = to[fail[u]][i];
}
}
}
bool f[N];
int match(char *s, int len) {
int now = 1;
rep(i, 1, len) f[i] = false; f[0] = true;
for (int u = 0, i = 1; i <= len; ++i) {
int c = s[i] - 'a';
now = (now << 1) & 2047;
while (u && !to[u][c]) u = fail[u];
if (to[u][c]) {
u = to[u][c];
if (now & trs[u]) f[i] = true;
}
now |= f[i];
}
drep(i, len, 1) if (f[i]) return i;
return 0;
}
int len;
char s[N];
int main() {
n = read(), m = read();
rep(i, 1, n) {
scanf("%s", s + 1), len = strlen(s + 1);
insert(s, len);
}
AC();
rep(i, 1, m) {
scanf("%s", s + 1), len = strlen(s + 1);
printf("%d\n", match(s, len));
}
return 0;
}