Hungry3

梦想到达塔顶的蜗牛

HDU 3065 病毒侵袭持续中 AC自动机

#include<cstdio>
#include<map>
#include<string>
#include<cstring>
#include<queue>
#include<iostream>
using namespace std;
map<int,string> hash;
const int max_node=30000+10;
const int son_num=200;
int cnt[1010];
class ACAutomaton
{
    private:
    int sz;
    int trie[max_node][son_num];
    int val[max_node];
    int fail[max_node];
    public:
    void init()
    {
        sz=0;
        memset(trie,0,sizeof(trie));
        memset(val,0,sizeof(val));
    }
    int idx(char c)
    {
        return c;
    }
    void insert(char *s,int key)
    {
        int u,c,n,i,j;
        u=0;
        n=strlen(s);
        for(i=0;i<n;i++)
        {
            c=idx(s[i]);
            if(!trie[u][c])trie[u][c]=++sz;
            u=trie[u][c];
        }
        val[u]=key;
    }
    void query(char *T)
    {
        int u,c,n,i,j;
        u=0;
        n=strlen(T);
        for(i=0;i<n;i++)
        {
            c=idx(T[i]);
            u=trie[u][c];
            if(val[u])print(u);
        }
    }
    void print(int u)
    {
        if(val[u])
        {
            cnt[val[u]]++;
            print(fail[u]);
        }
    }
    void getfail()
    {
        queue<int> q;
        int u,c,n,i,j,r,v;
        fail[0]=0;
        for(c=0;c<son_num;c++)
        {
            u=trie[0][c];
            if(u)
            {
                fail[u]=0;
                q.push(u);
            }
        }
        while(!q.empty())
        {
            r=q.front();q.pop();
            for(c=0;c<son_num;c++)
            {
                u=trie[r][c];
                if(!u)
                {
                    trie[r][c]=trie[fail[r]][c];
                    continue;
                }
                q.push(u);
                v=fail[r];
                while(v&&!trie[v][c])v=fail[v];
                fail[u]=trie[v][c];
            }
        }
    }
}ac;
char s[55];
char T[2000000+100];
int main()
{
    int i,j,n;
    while(scanf("%d",&n)!=EOF)
    {
        ac.init();
        hash.clear();
        for(i=1;i<=n;i++)
        {
            scanf("%s",s);
            hash[i]=string(s);
            ac.insert(s,i);
        }
        ac.getfail();
        memset(cnt,0,sizeof(cnt));
        scanf("%s",T);
        ac.query(T);
        for(i=1;i<=n;i++)
        if(cnt[i])
        {
            cout<<hash[i]<<": "<<cnt[i]<<endl;
        }
    }
}
View Code

 

posted on 2013-11-12 00:25  Hungry3  阅读(142)  评论(0)    收藏  举报

导航