hdu 5384 第一次写AC自动机

来源:互联网 发布:拉依达准则 c语言 编辑:程序博客网 时间:2024/06/14 18:12

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;}


0 0
原创粉丝点击