luogu3808 luogu3796 AC自动机(简单版) AC自动机(加强版)
纪念一下我一晚上写了八遍AC自动机
这是加强版的:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
int n, cnt[155], mp[155], len, maxn;
char a[155][75], b[1000005];
queue<int> d;
struct ACzdj{
int s[10505][26], val[10505], lst[10505], fai[10505], u, v, siz;
//lst[i]是节点i沿失配指针走时遇到的第一个单词节点编号
void clr(){
siz = maxn = 0;
memset(s, 0, sizeof(s));
memset(cnt, 0, sizeof(cnt));
memset(val, 0, sizeof(val));
memset(lst, 0, sizeof(lst));
memset(fai, 0, sizeof(fai));
}
void ins(int k){
u = 0;
len = strlen(a[k]);
for(int i=0; i<len; i++){
v = a[k][i] - 'a';
if(!s[u][v]) s[u][v] = ++siz;
u = s[u][v];
}
if(!val[u]) val[u] = k;
mp[k] = val[u];
}
void getFail(){
for(int i=0; i<26; i++)
if(s[0][i])
d.push(s[0][i]);
while(!d.empty()){
u = d.front();
d.pop();
for(int i=0; i<26; i++){
v = s[u][i];
if(v){
fai[v] = s[fai[u]][i];
lst[v] = val[fai[v]]?fai[v]:lst[fai[v]];
d.push(v);
}
else s[u][i] = s[fai[u]][i];
}
}
}
void query(){
u = 0;
len = strlen(b);
for(int i=0; i<len; i++){
u = s[u][b[i]-'a'];
if(val[u]) cnt[val[u]]++;
v = lst[u];
while(v){
cnt[val[v]]++;
v = lst[v];
}
}
for(int i=1; i<=n; i++)
maxn = max(maxn, cnt[i]);
printf("%d\n", maxn);
for(int i=1; i<=n; i++)
if(cnt[mp[i]]==maxn)
printf("%s\n", a[i]);
}
}ac;
int main(){
while(scanf("%d", &n)!=EOF){
if(!n) break;
ac.clr();
for(int i=1; i<=n; i++){
scanf("%s", a[i]);
ac.ins(i);
}
ac.getFail();
scanf("%s", b);
ac.query();
}
return 0;
}
这是简单版的:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
char a[1000005];
queue<int> d;
int n;
struct ACzdj{
int s[1000005][26], siz, u, v, len, val[1000005], mp[1000005], fai[1000005];
int cnt[1000005], lst[1000005];
void ins(int k){
u = 0;
len = strlen(a);
for(int i=0; i<len; i++){
v = a[i] - 'a';
if(!s[u][v]) s[u][v] = ++siz;
u = s[u][v];
}
if(!val[u]) val[u] = k;
mp[k] = val[u];
}
void getFail(){
u = 0;
for(int i=0; i<26; i++)
if(s[0][i])
d.push(s[0][i]);
while(!d.empty()){
u = d.front();
d.pop();
for(int i=0; i<26; i++){
v = s[u][i];
if(v){
fai[v] = s[fai[u]][i];
lst[v] = val[fai[v]]?fai[v]:lst[fai[v]];
d.push(v);
}
else s[u][i] = s[fai[u]][i];
}
}
}
void query(){
u = 0;
len = strlen(a);
for(int i=0; i<len; i++){
u = s[u][a[i]-'a'];
if(val[u]) cnt[val[u]]++;
v = lst[u];
while(v){
cnt[val[v]]++;
v = lst[v];
}
}
int ans=0;
for(int i=1; i<=n; i++)
if(cnt[mp[i]])
ans++;
cout<<ans<<endl;
}
}ac;
int main(){
cin>>n;
for(int i=1; i<=n; i++){
scanf("%s", a);
ac.ins(i);
}
ac.getFail();
scanf("%s", a);
ac.query();
return 0;
}
luogu3808 luogu3796 AC自动机(简单版) AC自动机(加强版)的更多相关文章
- 简单版AC自动机
简单版\(AC\)自动机 学之前听别人说起一直以为很难,今天学了简单版的\(AC\)自动机,感觉海星,只要理解了\(KMP\)一切都好说. 前置知识:\(KMP\)(有链接) 前置知识:\(Trie\ ...
- [模板][P3808]AC自动机(简单版)
Description: 求n个模式串中有几个在文本串中出现 Solution: 模板,详见代码: #include<bits/stdc++.h> using namespace std; ...
- 模板】AC自动机(简单版)
模板]AC自动机(简单版) https://www.luogu.org/problemnew/show/P3808 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保 ...
- 【模版】AC自动机(简单版)
题目背景 这是一道简单的AC自动机模版题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 题目描述 给定n个模式串和1个文本串,求有多少个模式串在文本 ...
- 洛谷P3808 【模板】AC自动机(简单版)
题目背景 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 管理员提示:本题数据内有重复的单词,且重复单词应该计算多次, ...
- 【模板】AC自动机(简单版)
我:“woc...AC自动机?” 我:“可以自动AC???” 然鹅... 大佬:“傻...” 我:“(⊙_⊙)?” 大佬:“缺...” 我:“......” (大佬...卒 | 逃...) emm.. ...
- 【刷题】洛谷 P3808 【模板】AC自动机(简单版)
题目背景 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 管理员提示:本题数据内有重复的单词,且重复单词应该计算多次, ...
- P3808 【模板】AC自动机(简单版)
题目背景 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 管理员提示:本题数据内有重复的单词,且重复单词应该计算多次, ...
- luogu P3808 【模板】AC自动机(简单版)
题目背景 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 管理员提示:本题数据内有重复的单词,且重复单词应该计算多次, ...
随机推荐
- DetachedCriteria的简单使用
一. DetachedCriteria使得hibernate能够对查询条件进行面向对象的方式来组装.其创建方式有两种: 1.1直接用class创建:DetachedCriteria criteria ...
- CSS中的定位机制
CSS3 中有三种定位机制 : 普通文档流 (text)| 浮动(float) | 定位(position) 普通文档流 就是CSS中默认的文本文档 普通流中,元素位置由文档顺序和元素性质决定,块级元 ...
- 移动端rem单位和px单位换算
rem单位是根据html元素的单位在页面根据不同的手机屏幕分辨率动态整体的按比例缩小或放大字体. 假如html{font-size: 14px;},那么1rem=14px; 一个div宽度48px,那 ...
- 新项目升级到JFinal3.5之后的改变-着重体验自动依赖注入
最近,JFinal3.5发布,喜大普奔,我也应JBolt用户的需求,将JBolt进行了升级,实现可配置自动注入开启,支持JFinal3.5的项目生成.具体可以看:JBolt升级日志 这等工作做完后,我 ...
- LR脚本示例之参数_变量介绍
Action(){ char *url = "127.0.0.1:1080"; char arr_url[1024]; //将url变量的值复制给p_url1参数 lr_save_ ...
- MySQL查询示例
use test; create table t1(tid smallint(5) unsigned auto_increment,tname varchar(50),tkecheng varchar ...
- lwz程序人生之启程
本人14年小本科毕业. 第一次接触电脑是小学4年级.当时,是小学公开课,老师让我们去电脑室秀一下.现在,我都记不得当时我第一次看到电脑室好奇呢?还是没感觉呢? 到初中上电脑课的时候,我才真正了解到电脑 ...
- Tarjan的学习笔记 求割边求割点
博主图论比较弱,搜了模版也不会用... 所以决心学习下tarjan算法. 割点和割边的概念不在赘述,tarjan能在线性时间复杂度内求出割边. 重要的概念:时间戟,就是一个全局变量clock记录访问结 ...
- SQLServer死锁
死锁的四个必要条件:互斥条件(Mutual exclusion):资源不能被共享,只能由一个进程使用.请求与保持条件(Hold and wait):已经得到资源的进程可以再次申请新的资源.非剥夺条件( ...
- mysq--索引模块
问题:为什么要 使用索引? --->快速查询数据,但是仅仅这么回答,就是不专业的!!! 应该要分为数据量少的时候,不适用索引,走全表扫描的话,查询速率也是很快的 数据量大的话,使用索引,查询速率 ...