zoukankan      html  css  js  c++  java
  • [HDU2222]Keywords Search(AC自动机)

    Keywords Search

    一道模板题,但对于我这种初学者来说也是不好做的。

    对于AC自动机的理解,本蒟蒻暂时还理解不好,不多说了。

    看看这个人的blog

    ——本题代码

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <queue>
     5 #define N 500005
     6 
     7 using namespace std;
     8 
     9 char s[N << 1];
    10 int T, n, sz, ans;
    11 int ch[N][26], val[N], fail[N];
    12 bool vis[N];
    13 queue <int> q;
    14 
    15 inline void clear()
    16 {
    17     n = sz = ans = 0;
    18     memset(ch, 0, sizeof(ch));
    19     memset(vis, 0, sizeof(vis));
    20     memset(val, 0, sizeof(val));
    21     memset(fail, 0, sizeof(fail));
    22 }
    23 
    24 inline void insert()
    25 {
    26     int i, x, len = strlen(s), now = 0;
    27     for(i = 0; i < len; i++)
    28     {
    29         x = s[i] - 'a';
    30         if(!ch[now][x]) ch[now][x] = ++sz;
    31         now = ch[now][x];
    32     }
    33     val[now]++;
    34 }
    35 
    36 inline void make_fail()
    37 {
    38     int i, now;
    39     while(!q.empty()) q.pop();
    40     //第二层特殊处理,将第二层节点的 fail 指针指向 root(其实就是0,也就不用管) 
    41     for(i = 0; i < 26; i++) 
    42      if(ch[0][i])
    43       q.push(ch[0][i]);
    44     while(!q.empty())
    45     {
    46         now = q.front(), q.pop();
    47         for(i = 0; i < 26; i++)
    48         {
    49             if(!ch[now][i])
    50             {
    51                 ch[now][i] = ch[fail[now]][i];
    52                 continue;
    53             }
    54             fail[ch[now][i]] = ch[fail[now]][i];
    55             q.push(ch[now][i]);
    56         }
    57     }
    58 }
    59 
    60 inline void ac()
    61 {
    62     int x, y, len = strlen(s), i, now = 0;
    63     for(i = 0; i < len; i++)
    64     {
    65         vis[now] = 1;
    66         x = s[i] - 'a';
    67         y = ch[now][x];
    68         while(y && !vis[y])
    69         {
    70             vis[y] = 1;
    71             ans += val[y];
    72             y = fail[y];
    73         }
    74         now = ch[now][x];
    75     }
    76 }
    77 
    78 int main()
    79 {
    80     int i;
    81     scanf("%d", &T);
    82     while(T--)
    83     {
    84         clear();
    85         scanf("%d", &n);
    86         for(i = 1; i <= n; i++)
    87         {
    88             scanf("%s", s);
    89             insert();
    90         }
    91         scanf("%s", s);
    92         make_fail();
    93         ac();
    94         printf("%d
    ", ans);
    95     }
    96     return 0;
    97 }
    View Code
  • 相关阅读:
    6. (在第五步的基础上展开)实现模板推送发送
    5. (全局唯一接口调用凭据)获取Access token
    3. openid的获取
    2. 验证服务器地址的有效性
    Java后端开发规范
    4. (自定义菜单和删除全部菜单)Springboot读取静态json文件
    Docker私有仓库搭建与部署
    Docker容器基础学习一
    运维日志切割--logrotate
    zookeeper学习
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/6751904.html
Copyright © 2011-2022 走看看