AC自动机模板

#include <bits/stdc++.h>
#define ll long long
#define eps 1e-7
using namespace std;
inline int read(){
    int x=0;int f=1;char ch=getchar();
    while(ch>'9'||ch<'0') {if(ch=='-') f=-1;ch=getchar();}
    while(ch<='9'&&ch>='0') {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int MAXN=1e+10;
struct node {
    int endflag;
    int value;
    int linkk[26];
    int fail;
}tree[500010];
int root=0;
int slen;
char str[1000100];
int q[1000010];
int len,n;
void buildtrie(int x,int node){
    int s=str[x]-'a';
    if(!tree[node].linkk[s]){
        tree[node].linkk[s]=++len;
        tree[len].endflag=0;
        tree[len].fail=root;
    }
    int nextnode=tree[node].linkk[s];
    if(x==slen-1){
        tree[nextnode].endflag++;
        return ;
    }
    buildtrie(x+1,nextnode);
}
void init(){
    cin>>n;
    memset(tree,0,sizeof(tree));
    for(int i=1;i<=n;i++){
        scanf("%s",str);
        slen=strlen(str);
        buildtrie(0,root);
    }
}
void buildac(){
   int head=0;
   int tail=0;
   q[++tail]=root;
   while(head<tail){
        int now=q[++head];
        for(int i=0;i<26;i++){
            if(tree[now].linkk[i]){
	            int nextnode=tree[now].linkk[i];
	            if(now!=root){
                    int temp=tree[now].fail;
	                while(temp!=root&&!tree[temp].linkk[i]){
	                    temp=tree[temp].fail;
	                }
	                tree[nextnode].fail=tree[temp].linkk[i];
	            }
	            q[++tail]=nextnode;
	        }
        }
    }
}
void find(){
    int ans=0;
    scanf("%s",str);
    int len=strlen(str);
    int now=root;
    for(int i=0;i<len;i++){
        int chindex=str[i]-'a';
        while(!tree[now].linkk[chindex]&&now!=root){
            now=tree[now].fail;
        }
        now=tree[now].linkk[chindex];
        int temp=now;
        while(temp!=root&&tree[temp].endflag>-1){
            ans+=tree[temp].endflag;
            tree[temp].endflag=-1;
            temp=tree[temp].fail;
        }
    }
    cout<<ans<<endl;
}
int main(){
    init();
    buildac();
    find();
    return 0;
}

  

posted @ 2018-04-17 07:57  zhangenming  阅读(124)  评论(0编辑  收藏  举报