病毒侵袭持续中 HDU - 3065 ac自动机模板题,判断是否出现过,并输出次数

自己写的不知道为什么,degug一下午,还是t,吐了
然后参考大佬的博客https://www.jianshu.com/p/af3cc413d299

#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=50005;
char s[1010][60];
int tree[M][128];
int num[M];
int fail[M];
int pos;
int vis[1100];
char str[2000100];
void insert(char *s,int cnt) {
    int len=strlen(s);
    int root=0;
    for(int i=0; i<len; i++) {
        int x=s[i];
        if(!tree[root][x]) {
            tree[root][x]=pos;
            pos++;
        }
        root=tree[root][x];
    }
    //标记序号 
    num[root]=cnt;
}
void getfail( ) {
    queue<int>qu;
    for(int i=0; i<128; i++) {
        if(tree[0][i]) {
            fail[tree[0][i]]=0;
            qu.push(tree[0][i]);
        }
    }
    while(!qu.empty( )) {
        int u=qu.front( );
        qu.pop( );
        for(int i=0; i<128; i++) {
            if(tree[u][i]) {
                fail[tree[u][i]]=tree[fail[u]][i];
                qu.push(tree[u][i]);
            } else 
                tree[u][i]=tree[fail[u]][i];
        }
    }
}
void query(char *s) {
    int len=strlen(s);
    int root=0;
    for(int i=0; i<len; i++) {
        int x=s[i];
        root=tree[root][x];
        for(int j=root; j&&num[j]; j=fail[j]) 
            vis[num[j]]++;
    }
}
int main( ) {
    int n;
    while(~scanf("%d",&n)) {
        pos=1;
        memset(fail,0,sizeof(fail));
        memset(tree,0,sizeof(tree));
        memset(vis,0,sizeof(vis));
        memset(num,0,sizeof(num));
        for(int i=1; i<=n; i++) 
        {
            scanf("%s",s[i]);
            insert( s[i] , i);
        }
        fail[0]=0;
        getfail( );
        scanf("%s",str);
        query(str);
        for(int i=1; i<=n; i++) 
            if(vis[i]!=0) 
                printf("%s: %d\n",s[i],vis[i]);
    }
    return 0;

}

猜你喜欢

转载自www.cnblogs.com/QingyuYYYYY/p/12526348.html
今日推荐