BZOJ 3172 AC自动机

思路:
AC自动机
不可以存下所有的字符串 怎么办呢
维护一个sum 使路径上所有经过的点 sum[x]++

在求fail指针的时候 顺便搞了个BFS序吧 倒着(顺着fail指针)往回加一下sum 就好啦

//By SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 1000500
#define M 26
char a[N];
int n;
struct AC_Automata{
    int ch[N][M],size,w[222],sum[N],f[N],q[N*M],head,tail;
    void insert(char s[],int num){
        int u=0;
        for(int i=0;s[i];i++){
            int v=s[i]-'a';
            if(!ch[u][v])ch[u][v]=++size;
            u=ch[u][v],sum[u]++;
        }
        w[num]=u;
    }
    void build(){
        f[0]=1000050,head=tail=0;
        while(head<=tail){
            int r=q[head++];
            for(int i=0;i<M;i++){
                int u=ch[r][i];
                if(!u)ch[r][i]=ch[f[r]][i];
                else q[++tail]=u,f[u]=ch[f[r]][i];
            }
        }
        work();
    }
    void work(){
        for(int i=tail;i>=0;i--)sum[f[q[i]]]+=sum[q[i]];
        for(int i=1;i<=n;i++)printf("%d\n",sum[w[i]]);
    }
}ac;
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%s",a),ac.insert(a,i);
    ac.build();
}

这里写图片描述

posted @ 2016-12-09 16:17  SiriusRen  阅读(104)  评论(0编辑  收藏  举报