【模板】AC自动机

来源:互联网 发布:淘宝修改我的评价 编辑:程序博客网 时间:2024/06/11 03:21

参考lrj白书

#include<iostream>#include<cstdio>#include<cstring>#include<queue>using namespace std;const int N=1000010;char S[N],SS[N];int n;struct AC{    queue<int>q;    int ch[N][27];    int f[N],last[N],cnt[N];    int ans;    int idx(char c){return c-'a'+1;}    int size,now;    void insert(char* ss){        now=0;        for(int i=0;ss[i];i++){            if(!ch[now][idx(ss[i])]) ch[now][idx(ss[i])]=++size;            now=ch[now][idx(ss[i])];        }        cnt[now]++;    }    void getfail(){        for(int i=1;i<=26;i++) if(ch[0][i]) q.push(ch[0][i]);        while(!q.empty()){            int r=q.front();q.pop();            for(int i=1;i<=26;i++){                int u=ch[r][i];                if(!u) {ch[r][i]=ch[f[r]][i];continue;}                q.push(u);                int v=f[r];                while(v && !ch[v][i]) v=f[v];                f[u]=ch[v][i];                last[u]=cnt[f[u]]?f[u]:last[f[u]];            }        }    }    void calc(int x){        if(x==0) return;        ans+=cnt[x];cnt[x]=0;calc(last[x]);    }    void find(char *s){        int j=0;        for(int i=0;s[i];i++){            int c=idx(s[i]);            j=ch[j][c];            if(cnt[j]) calc(j);            else calc(last[j]);        }    }};AC ac;int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    scanf("%s\n",S);    scanf("%d\n",&n);    for(int i=1;i<=n;i++) {        scanf("%s",SS);        ac.insert(SS);    }    ac.getfail();    ac.find(S);    printf("%d\n",ac.ans);    return 0;}
0 0
原创粉丝点击