传送门:https://www.luogu.org/problem/P3808

题解:是一个AC自动机的裸题了,注释加在代码里面了

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 5, sigma_size = 26;
int ch[maxn][sigma_size];
int tot; //结点总数
int ans = 0;
int f[maxn]; //失配函数
int last[maxn];//表示 i沿着失配指针往回走时,遇到的下一个单词结点(即是该单词的最后一个结点)的编号
int val[maxn]; //若值不为0表示该结点是单词的最后一个结点
char a[maxn];
char b[maxn];
void init()
{
tot = 1;
memset(val, 0, sizeof(val));
memset(ch, 0, sizeof(ch));
memset(f, 0, sizeof(f));
memset(last, 0, sizeof(last));
}
void insert(char *str)//将所有模式串构建成一个字典树
{
int p = 0;
int len = strlen(str);
for(int i = 0; i < len; i++)
{
int c = str[i] - 'a';
if(!ch[p][c])
{
ch[p][c] = tot++;
}
p = ch[p][c];
}
val[p] ++;//标记此结点为末尾 同时代表模式串中 相同的字符串有几个
}
void find(char *str)
{
int n = strlen(str);
int u = 0;
for(int i = 0; i < n; i++)
{
int s = str[i] - 'a';
while(u && !ch[u][s])
u = f[u];
u = ch[u][s];
if(val[u])
{
ans += val[u];
val[u] = 0;
}
else if(val[last[u]])//判断是否为单词的末尾结点
{
ans += val[last[u]];
val[last[u]] = 0;
}
}
}
void getfail()//通过BFS进行计算fail函数
{
queue<int> q;
f[0] = 0;
for(int c = 0; c < sigma_size; c++)
{
int u = ch[0][c];
if(u)//将所有根结点的孩子结点全部压入队列
{
f[u] = 0;//根结点的孩子结点失配只能跳到根结点
q.push(u);
last[u] = 0;
}
}
while(!q.empty())
{
int r = q.front();
q.pop();
for(int c = 0; c < sigma_size; c++)
{
int u = ch[r][c];
if(!u)
continue;//{ch[r][c]=ch[f[r]][c];continue}(则可以把while语句删除),路径压缩
q.push(u);
int v = f[r];
while(v && !ch[v][c])//沿着失配边走 直到可以匹配 和KMP类似
v = f[v];
f[u] = ch[v][c];
last[u] = val[f[u]] ? f[u] : last[f[u]];//last需要指向单词末尾 用val数组判断
}
}
}
int main(void)
{
int n;
scanf("%d", &n);
init();
for(int i = 1; i <= n; i++)
{
scanf("%s", a);
insert(a);//根据情况而定 还可以改为insert(a,value) ;表示该单词的权重
}
getfail();
scanf("%s", b);
find(b);
cout << ans << endl;
return 0;
}

洛谷 P3808 【模板】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. [模板][P3808]AC自动机(简单版)

    Description: 求n个模式串中有几个在文本串中出现 Solution: 模板,详见代码: #include<bits/stdc++.h> using namespace std; ...

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

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

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

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

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

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

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

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

  8. 洛谷P3808 【模板】AC自动机(简单版)

    题目背景 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 管理员提示:本题数据内有重复的单词,且重复单词应该计算多次, ...

  9. 【刷题】洛谷 P3808 【模板】AC自动机(简单版)

    题目背景 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 管理员提示:本题数据内有重复的单词,且重复单词应该计算多次, ...

随机推荐

  1. java课程之团队开发冲刺阶段2.8

    昨日总结: 1.具体情况已经写在了昨天的当日总结当中 遇到的问题: 1.toolbar的返回键与菜单键冲突,导致无法同时使用 今天的任务: 1.完整实现课程查询任务 当日总结: 1.完整实现,唯一的遗 ...

  2. linux部分环境搭建

    连接数据库: mysql -hrm-uf6b23117l3s5t69zjo.mysql.rds.aliyuncs.com -uwswl -pwswl@2019 显示用户: show databases ...

  3. 记Windows下初次使用dev C++进行socket编程过程

    记初次接触socket编程,在devC++使用Winsock进行socket编程的一个过程,通过在devC++创建2个项目分别是server.client程序项目,感受通过socket使client与 ...

  4. 《C Primer Plus》- 第二章 C语言概述

    本笔记写于2020年1月27日. 本系列文章参考的是<C Primer Plus>(第六版),其中里面会有笔者自己的相关补充. 以下示例均运行于macOS Catalina 10.15.2 ...

  5. 2.3 使用Android Studio 简单设计UI界面

    首先 创建一个新的项目找到app 文件目录下的layout的 activity_main.xml 因为Android Studio 是可视化的,所有操作都可以在图形界面进行. 该res 界面当中  d ...

  6. fastreport小入门

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

  7. 沙龙报名 | 京东云DevOps——自动化运维技术实践

    随着互联网技术的发展,越来越多企业开始认识DevOps重要性,在企业内部推进实施DevOps,期望获得更好的软件质量,缩短软件开发生命周期,提高服务稳定性.但在DevOps 的实施与落地的过程中,或多 ...

  8. 201703-1 分蛋糕 Java

    思路: 注意最后如果剩余蛋糕的重量小于k,也算一个人分到 import java.util.Scanner; public class Main { public static void main(S ...

  9. SQL基础教程(第2版)第2章 查询基础:练习题

    SELECT product_name, regist_date FROM Product WHERE regist_date > '2009-04-28'; ① ~ ③中的 SQL 语句都无法 ...

  10. sync实现windows与nginx主机端文件同步(参考文档)

    资源 Rsync官网:http://rsync.samba.org/ 简介 Rsync(remote sync)是类unix系统下的远程(LAN/WAN)数据镜像备份工具.可以实现Linux与linu ...