• HDU 2222 Keywords Search AC自动机模板题


      题意:给你一些单词和一个句子,问有多少个单词在这个句子上出现过。

      AC自动机裸题

      

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <string>
    #include <algorithm>
    #include <iostream>
    #include <queue>
    
    using namespace std;
    
    const int maxn = 1000001;
    queue <int> q;
    struct Tree
    {
        int ch[maxn][28], fail[maxn], count[maxn], tot, root;
        void clear()
        {
            root = tot = 0;
            memset(ch, -1, sizeof(ch));
            memset(fail, -1, sizeof(fail));
            memset(count, 0, sizeof(count));
        }
        void insert(char *str)
        {
            int x = root, len = strlen(str+1);
            for (int i = 1; i <= len; ++i)
            {
                int id = str[i]-'a';
                if (ch[x][id] == -1)
                    ch[x][id] = ++tot;
                x = ch[x][id];
            }
            count[x] ++;
        }
        void build()
        {
            q.push(root);
            while (!q.empty())
            {
                int x = q.front();
                q.pop();
                for (int i = 0; i < 26; ++i)
                    if (ch[x][i] != -1)
                    {
                        if (x == root)
                            fail[ch[x][i]] = root;
                        else
                        {
                            int y = fail[x];
                            while (y != -1)
                            {
                                if (ch[y][i] != -1)
                                {
                                    fail[ch[x][i]] = ch[y][i];
                                    break ;
                                }
                                y = fail[y];
                                
                            }
                            if (y == -1)
                                fail[ch[x][i]] = root;
                        }
                        q.push(ch[x][i]);
                    }
            }
        }
        int find(char *str)
        {
            int x = root, len = strlen(str+1), ret = 0;
            for (int i = 1; i <= len; ++i)
            {
                int id = str[i]-'a';
                while (ch[x][id] == -1 && x != root)
                    x = fail[x];
                x = ch[x][id];
                if (x == -1)
                    x = root;
                int y = x;
                while (y != root && count[y] != -1)
                {
                    ret += count[y];
                    count[y] = -1;
                    y = fail[y];
                }
            }
            return ret;
        }
    }T;
    int n;
    char str[maxn];
    
    int main()
    {
        int Case;
        scanf("%d", &Case);
        while (Case --)
        {
            T.clear();
            scanf("%d", &n);
            for (int i = 1; i <= n; ++i)
            {
                scanf("%s", str+1);
                T.insert(str);    
            }
            T.build();
            scanf("%s", str+1);
            printf("%d
    ", T.find(str));
        }
        return 0;
    }
  • 相关阅读:
    JAVA_NIO 与Netty框架
    Socket编程
    P3368树状数组2(树状数组//改段求点)
    P3373 树状数组1(树状数组//改点求段)
    树状数组
    P1197 星球大战(并查集+链式向前星)
    P2024 食物链(种类并查集||带权并查集)
    P1111 修复公路(kruscal+并查集)
    P1387 最大正方形+P1736 创意吃鱼法(矩形上的dp+预处理)
    P2330 繁忙的城市(krusal最小生成树)
  • 原文地址:https://www.cnblogs.com/-ZZB-/p/6411481.html
Copyright © 2020-2023  润新知