http://acm.fzu.edu.cn/problem.php?pid=2005

AC自动机 需要优化

否则超时

代码:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<algorithm>

#define LL long long

using namespace std;

const int INF=0x3f3f3f3f;
const int N=5500005;
const int M=255000;
const int K=26;
struct nodeTrie
{
    int v;
    int fail;
    int next[K];
    void initialize()
    {
        v=0;
        fail=-1;
        memset(next,-1,sizeof(next));
    }
}trie[M];
int cnt,root;
char s1[N];
char s[1005];
char pro[N];
int getNewNode()
{
    ++cnt;
    trie[cnt].initialize();
    return cnt;
}
void addWord(int p,char *s,int k)
{
    if(s[0]=='\0') return ;
    for(int i=0;s[i]!='\0';++i)
    {
        if(trie[p].next[s[i]-'A']==-1)
        trie[p].next[s[i]-'A']=getNewNode();
        p=trie[p].next[s[i]-'A'];
    }
    (trie[p].v)=k;
}
void init(int n)
{
    cnt=-1;
    root=getNewNode();
    for(int i=1;i<=n;++i)
    {
        gets(s);
        addWord(root,s,i);
    }
}
void bfs(int p)
{
    trie[p].fail=root;
    queue<int>qt;
    qt.push(p);
    while(!qt.empty())
    {
        int y;
        int x=qt.front();qt.pop();
        for(int i=0;i<K;++i)
        if(trie[x].next[i]!=-1)
        {
            qt.push(trie[x].next[i]);
            if(x==root)
            {trie[trie[x].next[i]].fail=root;continue;}
            y=trie[x].fail;
            while(y!=root&&trie[y].next[i]==-1)
            y=trie[y].fail;
            if(trie[y].next[i]!=-1)
            trie[trie[x].next[i]].fail=trie[y].next[i];
            else
            trie[trie[x].next[i]].fail=root;
        }
    }
}
int match(int p,char *s,int n)
{
    int wordCount=0;
    int l=0;
    while(s[l]!='\0')
    {
        while(trie[p].next[s[l]-'A']==-1&&p!=root)
        p=trie[p].fail;
        if(trie[p].next[s[l]-'A']!=-1)
        p=trie[p].next[s[l]-'A'];
        ++l;
        int fp=p;
        while(fp!=root)
        {
            if(trie[fp].v==-1)
            break;
            if(trie[fp].v>0)
            {++wordCount;}
            trie[fp].v=-1;
            fp=trie[fp].fail;
        }
        if(wordCount==n)
        break;
    }
    return wordCount;
}
int main()
{
    //freopen("data.in","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d ",&n);
        init(n);
        bfs(root);
        gets(s1);
        int m=0;
        for(int i=0;s1[i]!='\0';++i)
        if(s1[i]=='[')
        {
            int sum=0;
            for(++i;s1[i]>='0'&&s1[i]<='9';++i)
            sum=sum*10+s1[i]-'0';
            while(sum--)
            pro[m++]=s1[i];
            ++i;
        }else
        {
            pro[m++]=s1[i];
        }
        pro[m]='\0';
        //puts(pro);
        int ans=match(root,pro,n);
        reverse(pro,pro+m);
        ans+=match(root,pro,n-ans);
        printf("%d\n",ans);
    }
    return 0;
}

  

posted on 2013-03-22 22:04  夜->  阅读(183)  评论(0编辑  收藏  举报