[模板][P3808]AC自动机(简单版)

模板,详见代码:

#include<bits/stdc++.h>
using namespace std;
const int mxn=1e7+5;
char str[mxn],p[80];
queue<int > q;

namespace Trie {
    int tot,fail[mxn],val[mxn];
    int t[mxn][26];
    void ins(char *s) {
        int len=strlen(s),u=0;
        for(int i=0;i<len;++i) {
            if(!t[u][s[i]-'a']) t[u][s[i]-'a']=++tot;
            u=t[u][s[i]-'a'];
        }
        ++val[u];
    };
    void build() {
        for(int i=0;i<26;++i)
            if(t[0][i]) fail[t[0][i]]=0,q.push(t[0][i]);
        while(!q.empty()) {
            int u=q.front(); q.pop();
            for(int i=0;i<26;++i) {
                if(t[u][i]) fail[t[u][i]]=t[fail[u]][i],q.push(t[u][i]);
                else t[u][i]=t[fail[u]][i]; //类似于路径压缩的优化
            }
        }
    };
    int query(char *s) {
        int len=strlen(s),u=0,ans=0;
        for(int i=0;i<len;++i) {
            u=t[u][s[i]-'a']; //每次从大到小统计文本串以第i个字符结束的所有串
            for(int v=u;val[v]!=-1;v=fail[v])
                ans+=val[v],val[v]=-1; //剪枝,跳过无需再跳
        }
        return ans;
    };
}
using namespace Trie;

int main()
{
    int n; scanf("%d",&n);
    for(int i=1;i<=n;++i)
        scanf("%s",p),ins(p);
    build();
    scanf("%s",str);
    printf("%d",query(str));
    return 0;
}

原文地址:https://www.cnblogs.com/list1/p/10382849.html

时间: 2024-10-12 20:21:17

[模板][P3808]AC自动机(简单版)的相关文章

[模板]洛谷T3808 AC自动机(简单版)

1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cmath> 5 #include<ctime> 6 #include<cstdlib> 7 8 #include<string> 9 #include<stack> 10 #include<queue> 11 #include<vector> 1

luogu P3808 【模板】AC自动机(简单版)

二次联通门 : luogu P3808 [模板]AC自动机(简单版) /* luogu P3808 [模板]AC自动机(简单版) 手速越来越快了 10分钟一个AC自动机 一遍过编译 + 一边AC 感觉不错 我也就做做板子题了.. */ #include <iostream> #include <cstring> #include <cstdio> #include <queue> #define Max 1000009 void read (int &

模板】AC自动机(简单版)

模板]AC自动机(简单版) https://www.luogu.org/problemnew/show/P3808 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 管理员提示:本题数据内有重复的单词,且重复单词应该计算多次,请各位注意 题目描述 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. 输入输出格式 输入格式: 第一行一个n,表示模式串个数: 下面n行每行一个模式串: 下面一行一个文本串. 输

【模板】AC自动机

来自洛谷的两道AC自动机模板题: [模板]AC自动机(简单版) 题目背景 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 管理员提示:本题数据内有重复的单词,且重复单词应该计算多次,请各位注意 题目描述 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. 输入输出格式 输入格式: 第一行一个n,表示模式串个数: 下面n行每行一个模式串: 下面一行一个文本串. 输出格式: 一个数表示答案 输入输出样例 输

【学时总结&amp;模板时间】◆学时&#183;10 &amp; 模板&#183;3◆ AC自动机

◇学时·10 & 模板·3◇ AC自动机 跟着高中上课……讲AC自动机的扩展运用.然而连KMP.trie字典树都不怎么会用的我一脸懵逼<(_ _)> 花一上午自学了一下AC自动机 QwQ ? Trie树 字典树的一种(听说还有其他字典树,不清楚).每个节点代表一个字母,根节点相当于超级源点,根节点不表示字母.Trie树最大的特点是从根节点出发,沿着树边向下走,走过的节点会形成一个字符串.而一些节点是某一个单词的结尾,对于这种节点,我们一般会给它做一个标记(ovr). ? 构建Trie树

【题解】P3796【模板】AC自动机(加强版)

[题解]P3796 [模板]AC自动机(加强版) 记录当前\(cnt\)是第几个"星".记录第几个串是对应着第几个星. 这里补充一点对于\(AC\)自动机的理解.可能一直有个问题我没有想明白,就是打标记的点只有一个,然而匹配时,假若一个分支包括了另一个不同的分支该怎么办.实际上,我们可以在匹配的时候使用\(fail\)数组进行类似链式前向星的遍历,从而遍历到那个打标记的地方.那么问题来了,怎么保证链式前向星会遍历到那个打了标记的节点呢?答案就在\(gen\_fail\)的玄机里.\(g

P3808 【模板】AC自动机(简单版)

题意 AC自动机模版题. 传送门 Code #include <bits/stdc++.h> using namespace std; const int maxn = 1e6+10; int fail[maxn], e[maxn], tree[maxn][26], tot; void insert(char *t) { int p = 0; for (int x, i=0; t[i]; ++i) { x = t[i]-'a'; if(!tree[p][x]) tree[p][x] = ++t

【模板】AC自动机(简单版)

题目背景 通过套取数据而直接“打表”过题者,是作弊行为,发现即棕名. 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 管理员提示:本题数据内有重复的单词,且重复单词应该计算多次,请各位注意 题目描述 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. 输入格式 第一行一个n,表示模式串个数: 下面n行每行一个模式串: 下面一行一个文本串. 输出格式 一个数表示答案 输入输出样例 输入 #1复制 2 a

「LuoguP3808」 【模板】AC自动机(简单版)

题目背景 通过套取数据而直接“打表”过题者,是作弊行为,发现即棕名. 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 管理员提示:本题数据内有重复的单词,且重复单词应该计算多次,请各位注意 题目描述 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. 输入输出格式 输入格式: 第一行一个n,表示模式串个数: 下面n行每行一个模式串: 下面一行一个文本串. 输出格式: 一个数表示答案 输入输出样例 输入样