题目传送门

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

sol:AC自动机,在fail边的基础上再加一个last边,指向真正有效的节点,跳fail边改成跳last边来跳过无效点。

  • 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], last[MAXN];
    int cnt[MAXN], inde[MAXN]; int tot, root, _max;
    vector<int> vec; string str[];
    int add_node() {
    memset(son[tot], -, sizeof(son[tot]));
    cnt[tot] = ; inde[tot] = -;
    return tot ++;
    }
    void init() {
    tot = _max = ;
    root = add_node();
    }
    void insert(char* s, int id) {
    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];
    }
    inde[p] = id;
    str[id] = s;
    }
    void build() {
    queue<int> que;
    fail[root] = last[root] = root;
    for (int i = ; i < ; i++) {
    if (son[root][i] == -) son[root][i] = root;
    else {
    fail[son[root][i]] = root;
    last[son[root][i]] = root;
    que.push(son[root][i]);
    }
    }
    while (!que.empty()) {
    int p = que.front(); que.pop();
    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];
    if (inde[son[fail[p]][i]] != -)
    last[son[p][i]] = son[fail[p]][i];
    else
    last[son[p][i]] = son[last[p]][i];
    que.push(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];
    for (int tmp = p; tmp != root; tmp = last[tmp]) {
    if (inde[tmp] == -) continue;
    cnt[tmp] ++;
    if (cnt[tmp] > _max) {
    _max = cnt[tmp];
    vec.clear();
    vec.push_back(inde[tmp]);
    } else if (cnt[tmp] == _max) {
    vec.push_back(inde[tmp]);
    }
    }
    }
    }
    void output() {
    printf("%d\n", _max);
    sort(vec.begin(), vec.end());
    for (int i = ; i < vec.size(); i++)
    cout << str[vec[i]] << endl;
    }
    } ac;
    char s[];
    int main() {
    int n;
    while (scanf("%d", &n) && n) {
    ac.init();
    for (int i = ; i <= n; i++) {
    scanf("%s", s);
    ac.insert(s, i);
    }
    ac.build(); scanf("%s", s);
    ac.slove(s); ac.output();
    }
    return ;
    }

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

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

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

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

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

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

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

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

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

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

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

  6. 洛谷P1120 小木棍 [数据加强版](搜索)

    洛谷P1120 小木棍 [数据加强版] 搜索+剪枝 [剪枝操作]:若某组拼接不成立,且此时 已拼接的长度为0 或 当前已拼接的长度与刚才枚举的长度之和为最终枚举的答案时,则可直接跳出循环.因为此时继续 ...

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

    原题链接 Description 模板题啦~ Code //[模板]AC自动机(加强版) #include <cstdio> #include <cstring> int co ...

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

    洛谷题目传送门 先膜一发yyb巨佬 orz 想学ac自动机的话,推荐一下yyb巨佬的博客,本蒟蒻也是从那里开始学的. 思路分析 裸的AC自动机,这里就不讲了.主要是这题太卡时了,尽管时限放的很大了.. ...

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

    题目链接:https://www.luogu.com.cn/problem/P3796 AC自动机:复杂度$O( (N+M)\times L )$,N为模式串个数,L为平均长度,M为文章长度. ins ...

  10. 洛谷-P5357-【模板】AC自动机(二次加强版)

    题目传送门 -------------------------------------- 过年在家无聊补一下这周做的几道AC自动机的模板题 sol:AC自动机,还是要解决跳fail边产生的重复访问,但 ...

随机推荐

  1. day23(023-递归练习)

    23.01_File类递归练习(统计该文件夹大小) * 需求:1,从键盘接收一个文件夹路径,统计该文件夹大小(字节?) * * 从键盘接收一个文件夹路径 * 1,创建键盘录入对象 * 2,定义一个无限 ...

  2. java后台读取excel模板数据

    /** * 读取EXCEL模板数据 * * @param excelFilePath excel文件路径 * @param dataRowNum 开始读取数据的行数 * @param keyRowNu ...

  3. Neo4j--图形理论基础

    参考 https://www.w3cschool.cn/neo4j/neo4j_graph_theory_basics.html 节点 圆圈表示的是节点.节点是图表的基本单位. 节点可以用来存储数据, ...

  4. 福州大学2020年春软工实践W班第一次作业

    作业描述 这个作业属于哪个课程 福州大学2020年春软工实践W班 这个作业要求在哪里 寒假作业(1/2) 这个作业的目标 建立博客.回顾,我的初心.当下和未来.学习路线 作业正文 福州大学2020年春 ...

  5. tfield的字段名和显示名

    unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...

  6. da道至简读后感

    大道至简,衍化至繁. 往往特别深奥的事却是从特别简洁的发展而成的,就像麦克斯韦仅仅凭一个方程组就统一了电磁学一样,物理学中的算式往往非常简练.开普勒计算天体运行的时候是遵循老师认同的地心说计算的,结果 ...

  7. Microsoft SQL server Management Studio工具报错“应用程序的组件中发生了无法处理的异常”

    解决办法 打开目录: C:\Documents and Settings\Administrator\Application Data\Microsoft\Microsoft SQL Server\1 ...

  8. 【转帖】虚拟化Pod性能比裸机还要好,原因竟然是这样!

    虚拟化Pod性能比裸机还要好,原因竟然是这样! http://www.itpub.net/2020/02/27/5340/ 其实感觉 linux也可以做到 NUMA的节点优化 其实 直接在 ESXi上 ...

  9. cuda cudaTextureFilterMode

    cudaFilterModePoint:点模式,返回最接近的一个点,即最近邻插值.插值公式 tex(x) = T(i),i=floor(x),注意是对坐标向下取整,所以一般对输入坐标值+0.5,避免无 ...

  10. UML的用例图

    1.概念理解 (1)用例图是UML多种图形语言的一种,最能体现系统结构,直观展现系统功能模块模型 (2)用例图用于描述用户与用例(角色与功能模块)之间的关联关系 (3)常用Power Designer ...