zoukankan      html  css  js  c++  java
  • HDU 2222 Keywords Search AC自动机模版

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2222

    题意:给你n个单词和一个字符串,问有多少个单词出现过

    #include<bits/stdc++.h>
    using namespace std;
    const int N=500000+5;
    struct p
    {
        int next[N][26];
        int fail[N],cnt[N];
        int tot,root;
    
        int newnode()
        {
            for(int i=0;i<26;i++)
                next[tot][i]=-1;
            fail[tot]=-1;
            cnt[tot]=0;
            return tot++;
        }
        void init()
        {
            tot=0;
            root=newnode();
        }
        void add(char *s)
        {
            int now=root;
            int len=strlen(s);
            for(int i=0;i<len;i++)
            {
                if (next[now][s[i]-'a']==-1) next[now][s[i]-'a']=newnode();
                now=next[now][s[i]-'a'];
            }
            ++cnt[now];
        }
        void build()
        {
            queue<int> que;
            que.push(root);
            while(!que.empty())
            {
                int now=que.front();
                que.pop();
                for(int i=0;i<26;i++)
                {
                    if (next[now][i]==-1)
                    {
                        if (now==root) next[now][i]=root;
                        else next[now][i]=next[fail[now]][i];
                    }
                    else
                    {
                        if (now==root) fail[next[now][i]]=root;
                        else fail[next[now][i]]=next[fail[now]][i];
                        que.push(next[now][i]);
                    }
                }
            }
        }
        int match(char *s)
        {
            int now=root,ans=0;
            int len=strlen(s);
            for(int i=0;i<len;i++)
            {
                now=next[now][s[i]-'a'];
                for(int t=now;t!=root&&cnt[t]!=-1;t=fail[t])
                {
                    ans+=cnt[t];
                    cnt[t]=-1;
                }
            }
            return ans;
        }
    }ac;
    char s[1000005];
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            int n;
            scanf("%d",&n);
            ac.init();
            for(int i=1;i<=n;i++)
            {
                scanf("%s",s);
                ac.add(s);
            }
            ac.build();
            scanf("%s",s);
            printf("%d
    ",ac.match(s));
        }
        return 0;
    }
    

      

  • 相关阅读:
    poj2823单调队列认知
    有关二叉树的三序遍历的题目
    hdu4757 可持续字典树
    ZOJ2532判断边是否是割集中的边
    poj2455 k条路最小化最长边
    乘法逆元模板
    poj1699 KMP+壮压DP
    Innodb存储引擎——非聚集索引
    java集合框架笔记
    jvm垃圾回收
  • 原文地址:https://www.cnblogs.com/bk-201/p/8395476.html
Copyright © 2011-2022 走看看