hdu 5384 第一次写AC自动机

AC自动机算是kmp的升级版,第一次写这个,感觉很有收获

#include<stdio.h>
#include<string>
#include<map>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
const int N=1e5+10;
const int MOD=1e9+7;
int n,m,k;
char *str[N];
char *s[N];
struct node{
    node *son[26];
    int cnt;
    char ch;
    node *fail;
    node(){
        init();
    }
    void init(){
        cnt=0;
        for(int i=0;i<26;i++) son[i]=NULL;
        fail=0;
    }
};
node *root=new node(),*p,*tmp;
void insert(char *s){
    p=root;
    int i=0;
    while(s[i]){
        int u=s[i]-'a';
        if(p->son[u]!=0){
           p=p->son[u];
        }else{
            tmp=new node();
            p->son[u]=tmp;
            p=tmp;
            p->ch=s[i];
        }
        i++;
    }
    p->cnt++;
}
node * q[2600000+1];
void init_fail(){
    int l=0,r=-1;
    q[++r]=root;
    while(l<=r){
        p=q[l++];
        for(int i=0;i<26;i++) if(p->son[i]!=0){
            if(p==root){
                p->son[i]->fail=root;
            }else{
                tmp=p->fail;
                while(tmp!=NULL){
                    if(tmp->son[i]!=0) break;
                    else tmp=tmp->fail;
                }
                if(tmp!=NULL) {
                p->son[i]->fail=tmp->son[i];
                }
                else {
                p->son[i]->fail=root;
                }
            }
                   q[++r]=p->son[i];
        }
    }
}
long long query(char *s){
    p=root;
    long long res=0;
    int i=0;
    int len=strlen(s);
    for(int i=0;i<len;i++){
        int u=s[i]-'a';
         if(!p) p=root;
         while(p!=NULL && p->son[u]==0) p=p->fail;
         if(p==NULL) continue;
         p=p->son[u];
         res+=p->cnt;
        tmp=p;
        while(tmp!=NULL){
            tmp=tmp->fail;
                  if(tmp==NULL) break;
            res+=tmp->cnt;
        }
    }
    return res;
}
int main(){
#ifndef ONLINE_JUDGE
    freopen("aaa","r",stdin);
#endif
    int T;
    scanf("%d",&T);

    while(T--){
        scanf("%d%d",&n,&m);
        root->init();
        root->fail=NULL;
     char st[N];
        for(int i=0;i<n;i++){
            scanf("%s",st);
            str[i]=(char*) malloc((strlen(st)+5));
            strcpy(str[i],st);
        }
        for(int i=0;i<m;i++){
            scanf("%s",st);
            s[i]=(char*) malloc((strlen(st)+5));
            strcpy(s[i],st);
            insert(s[i]);
        }
        init_fail();
        for(int i=0;i<n;i++)
        printf("%I64d\n",query(str[i]));
    }
    return 0;
}


你可能感兴趣的:(hdu 5384 第一次写AC自动机)