HDU 2222 Keywords Search AC自动机

来源:互联网 发布:cc攻击防御 php 编辑:程序博客网 时间:2024/06/08 13:00

题目大意:有T组数据,每组数据中有n个模式串,给出一个主串,求出在主串中有多少个模式串出现过

AC自动机裸题。

AC自动机就是在Trie上做KMP,处理出在某位置失配后应该跳到什么位置,然后正常查询即可。
需要注意的是,还要处理一下不断地跳fail遇到第一个单词在什么位置,统计答案时也要统计一下。

板子在这里。

#include <cstdio>#include <cstring>#include <queue>#define N 1000005using namespace std;struct Node {    Node *ch[26],*nxt;    int val;    bool jud;    Node():nxt(NULL),val(0),jud(false) { for(int i=0;i<26;i++) ch[i]=NULL; }}*root;int n;char s[N];void Insert() {    Node* o=root;    int len=strlen(s);    for(int i=0;i<len;i++) {        int z=s[i]-'a';        if(o->ch[z]==NULL) o->ch[z]=new Node();        o=o->ch[z];    }    o->val++;    return ;}void getFail() {    queue<Node*> q;    Node *o=root;    for(int i=0;i<26;i++)        if(o->ch[i]!=NULL) q.push(o->ch[i]) , o->ch[i]->nxt=o;        else o->ch[i]=o;    while(!q.empty()) {        o=q.front(); q.pop();        for(int i=0;i<26;i++)            if(o->ch[i]!=NULL) q.push(o->ch[i]) , o->ch[i]->nxt=o->nxt->ch[i];            else o->ch[i]=o->nxt->ch[i];        Node *tmp=o;        tmp=tmp->nxt;        while(tmp!=root && !tmp->val) tmp=tmp->nxt;        o->nxt=tmp;    }    return ;}int ans;void Match() {    ans=0;    Node *o=root;    int len=strlen(s);    for(int i=0;i<len;i++) {        int z=s[i]-'a';        o=o->ch[z];        Node *tmp=o;        while(tmp!=root && !tmp->jud) {            ans+=tmp->val , tmp->jud=true;            tmp=tmp->nxt;        }    }    return ;}int main() {    int T;    scanf("%d",&T);    while(T--) {        root=new Node();        scanf("%d",&n);        while(n--) scanf("%s",s) , Insert();        getFail();        scanf("%s",s);        Match();        printf("%d\n",ans);    }    return 0;}
0 0