首页 > 代码库 > 暑假集训day9补充(AC自动机)

暑假集训day9补充(AC自动机)

推荐网站http://blog.csdn.net/niushuai666/article/details/7002823

AC自动机嘛,此AC(aho-corasick)非彼AC(Accepted)。

我也不是很会解释

有一题是必须打的hdu2222。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int mn=500010;
int ch[mn][26],siz,ro,val[mn],last[mn],f[mn];
int newnode(){
    memset(ch[siz],0,sizeof(ch[siz]));val[siz]=0;
    return siz++;
}
void init(){
    siz=1;ro=newnode();
}
void add(char *s){
    int u=ro,l=strlen(s);
    for(int i=0;i<l;i++){
        int c=s[i]-a;
        if(ch[u][c]==0)ch[u][c]=newnode();
        u=ch[u][c];
    }
    val[u]++;
}
void getfail(){
    queue<int>q;last[ro]=f[ro]=ro;
    for(int i=0;i<26;i++){
        int x=ch[ro][i];
        if(!x)ch[ro][i]=ro;
        else{q.push(x);f[x]=last[x]=ro;}
    }
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=0;i<26;i++){
            int v=ch[u][i];
            if(!v)ch[u][i]=ch[f[u]][i];
            else{
                q.push(v);f[v]=ch[f[u]][i];
                if(val[f[v]])last[v]=f[v];
                else last[v]=last[f[v]];
            }
        }
    }
}
int match(char *s){
    int u=ro,ans=0,l=strlen(s);
    for(int i=0;i<l;i++){
        u=ch[u][s[i]-a];
        int tmp=u;
        while(tmp!=ro){
            ans+=val[tmp];
            val[tmp]=0;
            tmp=last[tmp];
        }
    }
    return ans;
}
char text[1000010];
int main(){
    int T;scanf("%d",&T);
    while(T--){
        int n;scanf("%d",&n);init();
        for (int i=0;i<n;i++){
            scanf("%s",text);add(text);
        }
        getfail();scanf("%s",text);
        printf("%d\n",match(text));
    }
    return 0;
}

本文由Yzyet编写,网址为www.cnblogs.com/Yzyet。非Yzyet同意,禁止转载,侵权者必究。

暑假集训day9补充(AC自动机)