题目传送门

-------------------------------------- 过年在家无聊补一下这周做的几道AC自动机的模板题

sol:AC自动机,还是要解决跳fail边产生的重复访问,但是这次用last边已经不行了,只能拿76分。我们把跳fail边的过程放到串扫描完之后一次性进行。

  • AC自动机

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<int, int> PII;
    const int MAXN = ;
    struct Trie {
    int son[MAXN][], fail[MAXN];
    int que[MAXN]; int head, tail;
    int cnt[MAXN]; int tot, root;
    int add_node() {
    memset(son[tot], -, sizeof(son[tot]));
    cnt[tot] = ;
    return tot ++;
    }
    void init() {
    head = tail = ;
    tot = ;
    root = add_node();
    }
    int insert(char* s) {
    int p = root;
    for (int i = ; s[i]; i++) {
    int index = s[i] - 'a';
    if (son[p][index] == -)
    son[p][index] = add_node();
    p = son[p][index];
    }
    return p;
    }
    void build() {
    fail[root] = root;
    for (int i = ; i < ; i++) {
    if (son[root][i] == -) son[root][i] = root;
    else {
    fail[son[root][i]] = root;
    que[++ tail] = son[root][i];
    }
    }
    while (head != tail) {
    int p = que[++ head];
    for (int i = ; i < ; i++) {
    if (son[p][i] == -) son[p][i] = son[fail[p]][i];
    else {
    fail[son[p][i]] = son[fail[p]][i];
    que[++ tail] = son[p][i];
    }
    }
    }
    }
    void slove(char* s) {
    int p = root;
    for (int i = ; s[i]; i++) {
    int index = s[i] - 'a';
    p = son[p][index];
    cnt[p] ++;
    }
    for (int i = tail; i >= ; i--) {
    int p = que[i];
    cnt[fail[p]] += cnt[p];
    }
    }
    } ac;
    int inde[MAXN]; // 本地运行没什么问题,洛谷叫index就报编译错误
    char s[];
    int main() {
    int n; ac.init();
    scanf("%d", &n);
    for (int i = ; i <= n; i++) {
    scanf("%s", s);
    inde[i] = ac.insert(s);
    }
    ac.build();
    scanf("%s", s); ac.slove(s);
    for (int i = ; i <= n; i++)
    printf("%d\n", ac.cnt[inde[i]]);
    return ;
    }

    经过不断地40分、60分、76分,终于搞定了。为了在最后跳fail边的时候保证深度越高的节点越先跳采用了手写队列保留bfs时候的层次关系。网上看到别人的代码据说是用拓扑的,没细看。不过感觉这里的队列就是一个对深度的拓扑排序了。

洛谷-P5357-【模板】AC自动机(二次加强版)的更多相关文章

  1. 洛谷P3808 & P3796 AC自动机模板

    题目:P3808:https://www.luogu.org/problemnew/show/P3808 P3796:https://www.luogu.org/problemnew/show/P37 ...

  2. 洛谷 - P3966 - 单词 - AC自动机

    https://www.luogu.org/problemnew/show/P3966 因为文本串就是字典本身,所以这个和平时的AC自动机不太一样.平时的query要沿着fail树把子树的出现次数依次 ...

  3. 洛谷.3121.审查(AC自动机 链表)

    题目链接 //删掉一个单词需要前移一段位置,用链表维护就好了 复杂度O(sum(len)) #include <cstdio> #include <cstring> #defi ...

  4. 洛谷 - P2444 - 病毒 - AC自动机

    https://www.luogu.org/problemnew/show/P2444 有点恶心,不太明白fail的意义. #include<bits/stdc++.h> using na ...

  5. 洛谷 P3804 [模板] 后缀自动机

    题目:https://www.luogu.org/problemnew/show/P3804 模仿了一篇题解,感觉很好写啊. 代码如下: #include<cstdio> #include ...

  6. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

  7. 【洛谷 P5357】 【模板】AC自动机(二次加强版)(AC自动机,差分)

    每次匹配都不停跳fail显然太慢了,于是在每个节点和fail指向的点连一条边,构成一棵树,在这棵树上差分一下就好了. AC自动机 就这个算法而言其实没用想象中那么难. #include <cst ...

  8. 【AC自动机】洛谷三道模板题

    [题目链接] https://www.luogu.org/problem/P3808 [题意] 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. [题解] 不再介绍基础知识了,就是裸的模 ...

  9. 洛谷-P3796-【模板】AC自动机(加强版)

    题目传送门 -------------------------------------- 过年在家无聊补一下这周做的几道AC自动机的模板题 sol:AC自动机,在fail边的基础上再加一个last边, ...

随机推荐

  1. 适合初学者的10个linux命令

    转http://devopscube.com/list-of-linux-commands-every-developer-should-know/ At some point in you deve ...

  2. 吴裕雄--天生自然 JAVASCRIPT开发学习: Break 和 Continue 语句

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  3. 吴裕雄--天生自然 PHP开发学习:运算符

    <?php $x=10; $y=6; echo ($x + $y); // 输出16 echo '<br>'; // 换行 echo ($x - $y); // 输出4 echo ' ...

  4. Tensorflow学习教程------利用卷积神经网络对mnist数据集进行分类_利用训练好的模型进行分类

    #coding:utf-8 import tensorflow as tf from PIL import Image,ImageFilter from tensorflow.examples.tut ...

  5. 洛谷 P5663 加工零件

    题目传送门 解题思路: 最暴力的做法: bfs模拟,每次将一个阶段的所有点拿出来,将其所有直连的点都放进队列,知道本阶段结束,最后看1号点会不会在最后一个阶段被放入队列.(洛谷数据40分) 优化了一下 ...

  6. QMainWindow的空间布局结构

    简单讲一下Qt的QMainWindow的结构,Qt的顶级窗口有三种类型,首先是万恶之源(...应该说是大部分控件的父类...)的QWidget,然后是QMainWidget和QDialog,后面两者也 ...

  7. 关于域名转发proxy_pass

    在配置nginx的时候,有一个需求,访问m.XXX.com的时候,需要实际访问www.YYY.com/m,并且域名不能发生变化. 达成这个需求有两种做法: 第一种就是301跳转,使用rewrite来跳 ...

  8. sql注入入门--基本命令

    本文转载自http://blog.csdn.net/zgyulongfei/article/details/41017493 本文仅献给想学习渗透测试的sqlmap小白,大牛请绕过. > > ...

  9. (转)out.writer和out.print

    JSP中out.write()和out.print()的区别 out对象的类型是JspWriter.JspWriter继承了java.io.Writer类. 1)print方法是子类JspWriter ...

  10. UML-架构分析-基础

    1.何时开始架构分析? 最好在第一次迭代前开始.因为,架构分析的失败会导致高风险.如:必须支持英语.在一秒响应时间内支持500个并发事务. UP是迭代和进化的(不是瀑布式的),所以架构分析和开发工作齐 ...