zoukankan      html  css  js  c++  java
  • hdu2222(ac自动机模板)

    先推荐两篇写的很好的ac自动机blog:

    http://blog.csdn.net/creatorx/article/details/71100840

    http://blog.csdn.net/niushuai666/article/details/7002823

    正题

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

    题意: 给出 n 个模式串以及一个 主串, 问有多少个模式串在主串中出现过

    思路: ac自动机模板题

    代码:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <queue>
     5 using namespace std;
     6 
     7 const int MAXN = 5e5 + 10;
     8 
     9 struct Trie{
    10     int next[MAXN][26], fail[MAXN], end[MAXN];
    11     int root, L;
    12     int newnode(){//初始化字典树节点
    13         for(int i = 0; i < 26; i++){
    14             next[L][i] = -1;
    15         }
    16         end[L++] = 0;
    17         return L - 1;
    18     }
    19     void init(){//初始化字典树根节点
    20         L = 0;
    21         root = newnode();
    22     }
    23     void insert(char buf[]){//往字典树中插入一个单词
    24         int len = strlen(buf);
    25         int now = root;
    26         for(int i = 0; i < len; i++){
    27             if(next[now][buf[i] - 'a'] == -1) next[now][buf[i] - 'a'] = newnode();
    28             now = next[now][buf[i] - 'a'];
    29         }
    30         end[now]++;
    31     }
    32     void build(){ //构造fail数组
    33         queue<int> Q;
    34         fail[root] = root;
    35         for(int i = 0; i < 26; i++){
    36             if(next[root][i] == -1) next[root][i] = root;
    37             else{
    38                 fail[next[root][i]] = root;
    39                 Q.push(next[root][i]);
    40             }
    41         }
    42         while(!Q.empty()){
    43             int now = Q.front();
    44             Q.pop();
    45             for(int i = 0; i < 26; i++)
    46             if(next[now][i] == -1) next[now][i] = next[fail[now]][i];
    47             else{
    48                 fail[next[now][i]] = next[fail[now]][i];
    49                 Q.push(next[now][i]);
    50             }
    51         }
    52     }
    53     int query(char buf[]){
    54         int len = strlen(buf);
    55         int now = root;
    56         int res = 0;
    57         for(int i = 0; i < len; i++){
    58             now = next[now][buf[i] - 'a'];
    59             int temp = now;
    60             while(temp != root){
    61                 res += end[temp];
    62                 end[temp] = 0; // 每个模式串只算一次,所以清0
    63                 temp = fail[temp];
    64             }
    65         }
    66         return res;
    67     }
    68     void debug(){
    69         for(int i = 0; i < L; i++){
    70             printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],end[i]);
    71             for(int j = 0; j < 26; j++){
    72                 printf("%2d",next[i][j]);
    73             }
    74             printf("]
    ");
    75         }
    76     }
    77 };
    78 
    79 Trie ac;
    80 char buf[MAXN << 1];
    81 
    82 int main(void){
    83     int t, n;
    84     scanf("%d", &t);
    85     while(t--){
    86         ac.init();
    87         scanf("%d", &n);
    88         for(int i = 0; i < n; i++){
    89             scanf("%s", buf);
    90             ac.insert(buf);
    91         }
    92         ac.build();
    93         scanf("%s", buf);
    94         printf("%d
    ", ac.query(buf));
    95     }
    96     return 0;
    97 }
    View Code
  • 相关阅读:
    进入全屏 nodejs+express+mysql实现restful风格的增删改查示例
    WebAPI 实现前后端分离
    android 集成支付宝app支付(原生态)-包括android前端与java后台
    Windows 64 位系统下 Python 环境的搭建
    Es6主要特征详解
    js上传图片
    Python socket
    设置windows开机自启某个软件
    oracle导入导出数据
    mysql触发器,答题记录表同步教学跟踪(用户列表)
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/7420175.html
Copyright © 2011-2022 走看看