hdu2896(病毒侵袭)--AC自动机

来源:互联网 发布:网络制式按什么划分 编辑:程序博客网 时间:2024/06/05 23:03

过完年了,又回来集训。
年后第一题。
这道题写了一个晚上,可能太久没有写过了,有点生疏了。
最后还是请ztz大神来帮忙看了看。
总结:
1.AC自动机的数组是根据所输入模板的总字符来定。
2.对于tot=1,以及初始化的时候将它的儿子全指向自己都是必须的。
3.对于getans时不了解,就手动模拟。

纪念一下!!

#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>#include<cmath>#include<vector>#define For(aa,bb,cc) for(int aa=bb;aa<=cc;++aa)#define Set(aa,bb) memset(aa,bb,sizeof(aa))using namespace std;const int maxn=100010;struct Aho_corasick_automaton{    int trie[maxn][130],fail[maxn],q[maxn],w[maxn],ans[maxn],_,tot,n,m;    bool vis[maxn];    char all[maxn];    void init(){        tot=1;        For(i,0,128)trie[0][i]=1;        Set(fail,0);    }    int newnode(){        fail[++tot]=0;        vis[tot]=0;        For(i,0,127) trie[tot][i]=0;        return tot;    }    void insert(char *s,int id){        int len=strlen(s),p=1;        For(i,0,len-1){            int j=s[i];            p=trie[p][j]?trie[p][j]:trie[p][j]=newnode();        }        w[p]=id;        vis[p]=1;    }    void got(int now){        For(i,0,127){            int ls=trie[fail[now]][i];            if(trie[now][i]) fail[trie[now][i]]=ls,vis[trie[now][i]]|=vis[ls];            else trie[now][i]=ls;        }    }    void getfail(){        int f=0,l=1;        q[1]=1;        while(f<l){            int top=q[++f];            For(i,0,127){                if(trie[top][i]) q[++l]=trie[top][i];            }            got(top);        }    }    void getans(char *s){        int len=strlen(s),p=1;        For(i,0,len-1){            int j=s[i];            if(j>=33 && j<=126)            {                if(!trie[p][j])p=1;                p=trie[p][j];                if(!p)p=1;            }            else            {                p=1;                continue;            }            for(int l=p;l>1;l=fail[l]){                if(!vis[l])break;                if(w[l]) ans[++_]=w[l];            }        }    }    void work(){        init();        scanf("%d%d",&n,&m);        For(i,1,n){            scanf("%s",all);            insert(all,i);        }        getfail();        scanf("%d",&m);        int sum=0;        For(i,1,m){            scanf("%s",all);            _=0;            getans(all);            if(!_) continue;            sort(ans+1,ans+_+1);            ++sum;            printf("web %d: ",i);            For(j,1,_-1) printf("%d ",ans[j]);            printf("%d",ans[_]);            puts("");        }        printf("total: %d",sum);        puts("");    }}d;int main(){    d.work();    return 0;}
1 0