Dominating Patterns (AC 自动鸡模版题, 出现次数最多的子串)

传送门

题意: 给你n个模式串, 再给你一个 文本串,问模式串在文本串中出现次数最多是多少。

   出现次数最多的模式串有哪些。

解: 模版题。

#include <bits/stdc++.h>
#define LL long long
#define rep(i, j, k) for(int i = j; i <= k; i++)
#define dep(i, j, k) for(int i = k; i >= j; i--)
#define mem(i, j) memset(i, j, sizeof(i))
using namespace std;
const int N = 150 * 70 + 5, M = 26;
map<string, int> vis;
char s[1000005], b[155][100];
struct Trie {
    int a[N][M], tot, val[N], Fail[N];
    void init() {
        mem(a[0], -1); tot = 1; val[0] = -1;
    }
    int get(char Q) {
        return Q - 'a';
    }
    void join(char s[], int v) {
        int len = strlen(s); int now = 0;
        rep(i, 0, len - 1) {
            int id = get(s[i]);
            if(a[now][id] == -1) {
                mem(a[tot], -1);
                val[tot] = -1;
                a[now][id] = tot++;
            }
            now = a[now][id];
        }
        val[now] = v;
    }
    void getFail() {
        queue<int>Q;  while(!Q.empty()) Q.pop();
        Fail[0] = 0;
        rep(i, 0, M - 1) {
            if(a[0][i] == -1) a[0][i] = 0;
            else {
                Fail[a[0][i]] = 0;
                Q.push(a[0][i]);
            }
        }
        while(!Q.empty()) {
            int now = Q.front(); Q.pop();
            rep(i, 0, M - 1) {
                if(a[now][i] == -1) a[now][i] = a[Fail[now]][i];
                else {
                    Fail[a[now][i]] = a[Fail[now]][i];
                    Q.push(a[now][i]);
                }
            }
        }
    }
    int num[155];
    void query(char s[], int n) {
        mem(num, 0);
        int len = strlen(s);
        int now = 0;
        rep(i, 0, len - 1) {
            now = a[now][get(s[i])];
            int tmp = now;
            while(tmp != 0) {
                if(val[tmp] != -1) num[val[tmp]]++;
                tmp = Fail[tmp];
            }
        }
        int ma = 0;
        rep(i, 1, n) {
            ma = max(ma, num[i]);
        }
        printf("%d\n", ma);
        rep(i, 1, n) {
            if(num[vis[b[i]]] == ma) {
                printf("%s\n", b[i]);
            }
        }
    }
};
Trie AC;
int main() {
    int n;
    while(scanf("%d", &n) && n) {
        AC.init(); vis.clear();
        rep(i, 1, n) {
            scanf("%s", b[i]);
            AC.join(b[i], i);
            vis[b[i]] = i;
        }
        AC.getFail();
        scanf("%s", s);
        AC.query(s, n);
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/Willems/p/12001225.html