【洛谷 P5357】 【模板】AC自动机(二次加强版)(AC自动机,差分)
每次匹配都不停跳fail显然太慢了,于是在每个节点和fail指向的点连一条边,构成一棵树,在这棵树上差分一下就好了。
AC自动机 就这个算法而言其实没用想象中那么难。
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
struct Node{
int fail, next[26], num;
}AC[200010];
int n, u, cnt;
queue <int> q;
int p[200010], vis[200010];
char a[2000010];
int f[200010];
struct Edge{
int next, to;
}e[200010];
int head[200010], num;
inline void Add(int from, int to){
e[++num].to = to; e[num].next = head[from]; head[from] = num;
}
void insert(int x){
int len = strlen(a + 1), w;
u = 0;
for(int i = 1; i <= len; ++i){
w = a[i] - 'a';
if(!AC[u].next[w])
AC[u].next[w] = ++cnt;
u = AC[u].next[w];
}
f[x] = u;
}
void BuildFail(){
u = 0;
for(int i = 0; i < 26; ++i)
if(AC[u].next[i])
q.push(AC[u].next[i]);
while(q.size()){
u = q.front(); q.pop();
for(int i = 0; i < 26; ++i)
if(AC[u].next[i]){
q.push(AC[u].next[i]);
AC[AC[u].next[i]].fail = AC[AC[u].fail].next[i];
}
else
AC[u].next[i] = AC[AC[u].fail].next[i];
}
}
void Match(){
int len = strlen(a + 1);
u = 0;
for(int i = 1; i <= len; ++i){
u = AC[u].next[a[i] - 'a'];
++vis[u];
}
}
void dfs(int x){
for(int i = head[x]; i; i = e[i].next){
dfs(e[i].to); vis[x] += vis[e[i].to];
}
}
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; ++i) f[i] = i;
for(int i = 1; i <= n; ++i){
scanf("%s", a + 1);
insert(i);
}
scanf("%s", a + 1);
BuildFail();
Match();
for(int i = 1; i <= cnt; ++i)
Add(AC[i].fail, i);
dfs(0);
for(int i = 1; i <= n; ++i)
printf("%d\n", vis[f[i]]);
return 0;
}
【洛谷 P5357】 【模板】AC自动机(二次加强版)(AC自动机,差分)的更多相关文章
- 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)
To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...
- 洛谷-P5357-【模板】AC自动机(二次加强版)
题目传送门 -------------------------------------- 过年在家无聊补一下这周做的几道AC自动机的模板题 sol:AC自动机,还是要解决跳fail边产生的重复访问,但 ...
- 【AC自动机】洛谷三道模板题
[题目链接] https://www.luogu.org/problem/P3808 [题意] 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. [题解] 不再介绍基础知识了,就是裸的模 ...
- 洛谷-P3796-【模板】AC自动机(加强版)
题目传送门 -------------------------------------- 过年在家无聊补一下这周做的几道AC自动机的模板题 sol:AC自动机,在fail边的基础上再加一个last边, ...
- 洛谷P3375 [模板]KMP字符串匹配
To 洛谷.3375 KMP字符串匹配 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.如果 ...
- LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)
为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...
- 洛谷P5283 & LOJ3048:[十二省联考2019]异或粽子——题解
https://www.luogu.org/problemnew/show/P5283 https://loj.ac/problem/3048 小粽是一个喜欢吃粽子的好孩子.今天她在家里自己做起了粽子 ...
- 洛谷P4608 [FJOI2016]所有公共子序列问题 【序列自动机 + dp + 高精】
题目链接 洛谷P4608 题解 建个序列自动机后 第一问暴搜 第二问dp + 高精 设\(f[i][j]\)为两个序列自动机分别走到\(i\)和\(j\)节点的方案数,答案就是\(f[0][0]\) ...
- 洛谷.1919.[模板]A*B Problem升级版(FFT)
题目链接:洛谷.BZOJ2179 //将乘数拆成 a0*10^n + a1*10^(n-1) + ... + a_n-1的形式 //可以发现多项式乘法就模拟了竖式乘法 所以用FFT即可 注意处理进位 ...
随机推荐
- Linux+Tomcat环境下安装SSL证书
1.将申请好的证书(4个文件)文件放入/home/tomcat/apache-tomcat-9.0.12/conf/cert文件夹下2.(或者)将申请好的证书(4个文件)文件放入/home/tomca ...
- Confd+Consul 动态生成配置文件
一.Consul安装和配置 1.consul是什么? consul是HashiCorp公司推出的一款工具,主要用于实现分布式系统的服务发现与配置,它提供了以下几个关键特性: 服务发现:Consul客户 ...
- java.lang.Thread类的静态方法sleep()和yield()的比较
[线程让步yield()方法] yield()方法可以让当前正在执行的线程暂停,但它不会阻塞该线程,它只是将该线程从运行状态转入就绪状态. 只是让当前的线程暂停一下,让系统的线程调度器重新调度一次. ...
- 以SQL命令方式调用存储过程
string str = "Data Source=.;Initial Catalog=***;Integrated Security=True"; using (SqlConne ...
- MySQL日常监控及sys库的使用【转】
一.统计信息(SQL维度) 关于SQL维度的统计信息主要集中在events_statements_summary_by_digest表中,通过将SQL语句抽象出digest,可以统计某类SQL语句在各 ...
- Python集成开发环境(IDE:Integrated Development Environment): PyCharm
原文地址:https://www.runoob.com/python/python-install.html IDE下载安装 PyCharm 是由 JetBrains 打造的一款 Python IDE ...
- Layui 点击查询分页,页码不刷新解决方法
Layui 点击查询分页,页码不刷新解决方法 function queryDataGrid() { layui.table.reload(tableName, { where: { //设定异步数据接 ...
- 高性能Java代码的规范
代码优化的目标是 减小代码的体积 提高代码运行的效率 代码优化细节 1.尽量指定类.方法的final修饰符 带有final修饰符的类是不可派生的.在Java核心API中,有许多应用final的例子,例 ...
- LeetCode 556. 下一个更大元素 III(Next Greater Element III)
556. 下一个更大元素 III 556. Next Greater Element III 题目描述 给定一个 32 位正整数 n,你需要找到最小的 32 位整数,其与 n 中存在的位数完全相同,并 ...
- Python Web开发技术栈