萌新求助
查看原帖
萌新求助
143744
elimva楼主2021/7/1 13:47

一直是 8080 分,思路就是把转移压缩,不知道错在哪里了,代码应该写的比较清晰,有哪位神仙哥哥可以说一下坑点或 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;
}
2021/7/1 13:47
加载中...