LuoguP3796 【模板】AC自动机(加强版)

link

链接

code

#include <iostream>
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>

const int N = 1e6 + 10;
using namespace std;

struct Ans{
    
    
    int num,  pos;
}ans[N];

bool cmp(Ans a, Ans b){
    
    
    if (a.num != b.num){
    
    
        return a.num > b.num;
    }else{
    
    
        return a.pos < b.pos;
    }
}

struct Automation{
    
    
    int c[N][26], exist[N], fail[N];
    int cnt;
    queue<int> q;

    void ins(char *s, int num){
    
    
        int now = 0, len = strlen(s);
        for (int i = 0; i < len; ++i) {
    
    
            if (!c[now][s[i] - 'a']) c[now][s[i] - 'a'] = ++cnt;
            now = c[now][s[i] - 'a'];
        }
        exist[now] = num;
    }

    void build(){
    
    
        for (int i = 0; i < 26; ++i) {
    
    
            if (c[0][i]) q.push(c[0][i]), fail[c[0][i]] = 0;
        }

        while (!q.empty()){
    
    
            int u = q.front();q.pop();
            for (int i = 0; i < 26; ++i) {
    
    
                if (c[u][i]) fail[c[u][i]] = c[fail[u]][i], q.push(c[u][i]);
                else c[u][i] = c[fail[u]][i];
            }
        }
    }

    void query(char *s){
    
    
        int now = 0, len = strlen(s);
        for (int i = 0; i < len; ++i) {
    
    
            now = c[now][s[i] - 'a'];
            for (int t = now; t; t = fail[t]) {
    
    
                ans[exist[t]].num++;
            }
        }
    }

    void clear(){
    
    
        cnt = 0;
        memset(c, 0, sizeof c);
        memset(exist, 0, sizeof exist);
        memset(fail, 0, sizeof fail);
    }
}AC;

int main() {
    
    
    int n; char s[200][200];
    while (true){
    
    
        scanf("%d", &n);
        if (n == 0) break;
        AC.clear();
        for (int i = 1; i <= n; ++i) {
    
    
            scanf("%s", s[i]);
            ans[i].num = 0;
            ans[i].pos = i;
            AC.ins(s[i], i);
        }
        AC.build();
        char p[N];
        scanf("%s", p);
        AC.query(p);
        sort(ans + 1, ans + n + 1, cmp);
        printf("%d\n", ans[1].num);
        printf("%s\n", s[ans[1].pos]);
        for (int i = 2; i <= n; ++i) {
    
    
            if (ans[i].num == ans[i - 1].num){
    
    
                printf("%s\n", s[ans[i].pos]);
            }else{
    
    
                break;
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_50070650/article/details/114275760