AC自动机

AC自动机 - AcWing 1282 - 搜索关键词

#include <bits/stdc++.h>
#define maxn 510000
using namespace std;

int t,n,cnt;
int trie[maxn][26];
int fail[maxn];
int word[maxn];

void init(){
    for(int i=0;i<maxn;i++){
        for(int j=0;j<26;j++) trie[i][j] = 0;
        fail[i] = word[i] = 0;
    }
    cnt = 0;
}

void insert(string s){
    int root = 0;
    for(int i=0;i<s.size();i++){
        int p = s[i]-'a';
        if(!trie[root][p]) trie[root][p] = ++cnt;
        root = trie[root][p];
    }
    word[root]++;
}

void getfail(){
    queue<int> q;
    for(int i=0;i<26;i++){
        if(trie[0][i]){
            fail[trie[0][i]] = 0;
            q.push(trie[0][i]);
        }
    }
    while(!q.empty()){
        int tmp = q.front();
        q.pop();
        for(int i=0;i<26;i++){
            int m = trie[tmp][i];
            if(m){
                fail[m] = trie[fail[tmp]][i];
                q.push(m);
            }
            else
                trie[tmp][i] = trie[fail[tmp]][i];
        }
    }
}

void query(string s){
    int ans = 0;
    int root = 0;
    for(int i=0;i<s.size();i++){
        root = trie[root][s[i]-'a'];
        for(int j = root; j ; j = fail[j]){
            if(word[j]){
                ans += word[j];
                word[j] = 0;
            }
        }
    }
    printf("%d
",ans);
}

int main(){
    scanf("%d",&t);
    while(t--){
        init();
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            string s;
            cin>>s;
            insert(s);
        }
        getfail();
        string s;
        cin>>s;
        query(s);
    }
}
---- suffer now and live the rest of your life as a champion ----
原文地址:https://www.cnblogs.com/popodynasty/p/14401235.html