码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj3172 Ac自动机

时间:2017-05-23 18:54:24      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:space   view   nbsp   cst   display   自动机   blog   hid   string   

根据fail树的性质 我们在建树的时候每建一个串就将他路径上的点全部加1表示这个串的后缀又出现了一次 然后从下到上把sum加起来就可以得到答案了
技术分享
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int size=26,M=1000005;
char c[M];
int w[255],n;
struct node{
    int sum,fail[M],a[M][27],ans[M];
    int id(char s){return s-a+1;}
    void insert(char s[],int &x){
        int k=0,L=strlen(s);
        for(int i=0;i<L;i++){
            int now=id(s[i]);
            if(!a[k][now]) a[k][now]=++sum;
            ans[a[k][now]]++; 
            k=a[k][now];
        }
        x=k;
    }
    int q[M],head,tail;
    void Ac_boy(){
        for(int i=1;i<=size;i++){
            int now=a[0][i];
            if(now) q[tail++]=now;
        }
        while(head!=tail){
            int x=q[head++];
            for(int i=1;i<=size;i++){
                int now=a[x][i];
                if(!now){a[x][i]=a[fail[x]][i];continue;}
                q[tail++]=now;
                fail[now]=a[fail[x]][i];
            }
        }
    }
    void work(){
        for(int i=tail-1;i>=0;i--) ans[fail[q[i]]]+=ans[q[i]];
        for(int i=1;i<=n;i++) printf("%d\n",ans[w[i]]);
    }
}node;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%s",c),node.insert(c,w[i]);
    node.Ac_boy(); node.work();
    return 0;
}
View Code

 

bzoj3172 Ac自动机

标签:space   view   nbsp   cst   display   自动机   blog   hid   string   

原文地址:http://www.cnblogs.com/lyzuikeai/p/6895371.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!