luogu P3796【模板】AC自动机(加强版)
这个和某谷的AC自动机模板简单版差不多。
但还是要注意几点的:
1.这个是统计出现次数,而不是是否出现,所以在查询的时候加上这个节点的val后,不能把val标记为-1。那么也就可以说查询的时间复杂度能比简单版的稍微第一慢一点。
2.考虑k个一样的模式串:刚开始我想的是每一个节点开一个vector,记录这里是第几个模式串。但其实没有这个必要,对于相同的模式串,我们只用记录任意一个就行,反而在出现次数上要都加上。因为如果主串中存在这些相同的模式串,那么出现次数应该是出现次数 * k。输出的时候如果是这些串最多,那么都应该把这些输出。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<stack>
#include<queue>
#include<vector>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define rg register
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-;
const int maxn = 1e6 + ;
const int maxm = 1.05e4 + ;
inline ll read()
{
ll ans = ;
char ch = getchar(), las = ' ';
while(!isdigit(ch)) las = ch, ch = getchar();
while(isdigit(ch)) ans = ans * + ch - '', ch = getchar();
if(las == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < ) putchar('-'), x = -x;
if(x >= ) write(x / );
putchar(x % + '');
} int n;
char s[maxn], ss[][]; int sum[];
int ch[maxm][], val[maxm], pos[maxm], f[maxm], cnt = ;
int getnum(char c)
{
return c - 'a';
}
void insert(int id, char *s)
{
int m = strlen(s);
int now = ;
for(int i = ; i < m; ++i)
{
int c = getnum(s[i]);
if(!ch[now][c]) ch[now][c] = ++cnt;
now = ch[now][c];
}
val[now]++; pos[now] = id;
}
void build()
{
queue<int> q;
for(int i = ; i < ; ++i) if(ch[][i]) q.push(ch[][i]);
while(!q.empty())
{
int now = q.front(); q.pop();
for(int i = ; i < ; ++i)
{
if(ch[now][i]) f[ch[now][i]] = ch[f[now]][i], q.push(ch[now][i]);
else ch[now][i] = ch[f[now]][i];
}
}
}
void query(char *s)
{
int m = strlen(s), now = ;
for(int i = ; i < m; ++i)
{
int c = getnum(s[i]);
now = ch[now][c];
for(int j = now; j; j = f[j]) sum[pos[j]] += val[j];
}
} void init()
{
Mem(ch, ); Mem(val, ); Mem(pos, ); Mem(f, );
Mem(sum, );
cnt = ;
} int main()
{
while(scanf("%d", &n) && n)
{
init();
for(int i = ; i <= n; ++i)
{
scanf("%s", ss[i]);
insert(i, ss[i]);
}
build();
scanf("%s", s);
query(s);
int Max = -;
for(int i = ; i <= n; ++i) Max = max(Max, sum[i]);
write(Max); enter;
for(int i = ; i <= n; ++i) if(sum[i] == Max) printf("%s\n", ss[i]);
}
return ;
}
luogu P3796【模板】AC自动机(加强版)的更多相关文章
- luoguP3796[模板]AC自动机(加强版)
传送门 ac自动机模板,可能我写的ac自动机是有点问题的,所以跑的有些慢 暴力跳fail统计 代码: #include<cstdio> #include<iostream> # ...
- luoguP3808[模板]AC自动机(简单版)
传送门 ac自动机模板题,裸的多串匹配 代码: #include<cstdio> #include<iostream> #include<algorithm> #i ...
- 算法模板——AC自动机
实现功能——输入N,M,提供一个共计N个单词的词典,然后在最后输入的M个字符串中进行多串匹配(关于AC自动机算法,此处不再赘述,详见:Aho-Corasick 多模式匹配算法.AC自动机详解.考虑到有 ...
- 模板 AC自动机
题目描述 有$N$ 个由小写字母组成的模式串以及一个文本串$T$ .每个模式串可能会在文本串中出现多次.你需要找出哪些模式串在文本串$T$ 中出现的次数最多. 输入输出格式 输入格式: 输入含多组数据 ...
- 算法竞赛模板 AC自动机
AC自动机基本操作 (1) 在AC自动机中,我们首先将每一个模式串插入到Trie树中去,建立一棵Trie树,然后构建fail指针. (2) fail指针,是穿插在Trie树中各个结点之间的指针,顾名思 ...
- [模板][P3796]AC自动机(加强版)
Description: 输出有哪些模式串在文本串中出现次数最多,这个次数是多少 Hint: 多组数据,$ len_{文本串}<=10^6,\sum len_{模式串} <= 70*150 ...
- 【模板】AC自动机加强版
题目大意:给定 N 个模式串和一个文本串,求每个模式串在文本串中出现的次数. 题解:文本串在自动机上匹配的过程中,记录下自动机上每一个状态被访问的次数.对于访问到的节点 i,则状态 i 的后缀中存在的 ...
- 洛谷.3808/3796.[模板]AC自动机
题目链接:简单版,增强版 简单版: #include <cstdio> #include <cstring> const int N=1e6+5,S=26; char s[N] ...
- 模板—AC自动机
#include<iostream> #include<cstdio> #include<cstring> using namespace std; struct ...
- 模板——AC自动机
传送门:QAQQAQ 定义nxt[u]=v表示从u开始不断沿着失配边跳到的第一个是标记点的端点v,那么我们再匹配时沿着last跳,每跳到一个last,它就一定对应一个模式串,所以效率是非常高的. 和K ...
随机推荐
- js动态给textarea赋值
document.getElementById("new_analysed_news").value=datas.weatherContent;
- Murano Weekly Meeting 2016.08.16
Meeting time: 2016.August.16 1:00~2:00 Chairperson: Kirill Zaitsev, from Mirantis Meeting summary: ...
- 下载Dubbo源码后的编译安装启动
1:安装jdk,maven 配制环境变量: 2:安装zookeeper 配制zookeeper环境变量 3:把dubbo源码编译成war包 启动cmd黑窗口 ,进入 源码文件 ...
- Root用户让其他用户运行某程序
这里以启动tomcat为例 1.安装tomcat不介绍了,自己百度 2.测试能否使用,略 3.创建tomcat用户 useradd tomcat -s /sbin/nologin 创建tomcat,禁 ...
- 把linux图形启动界面修改成命令行界面
由于图形界面比较耗资源,需要把启动界面修改成命令行界面,怎么修改呢? 1.vim /etc/inittab 2.把id:5:initdefault:改成 id:3:initdefault: 3.重启即 ...
- 抽象工厂模式&简单工厂模式
抽象工厂模式 优点: 如IFactory factory=new AccessFactory(),在一个应用中只需要初始化一次,这就使得改变应用的时候变得非常容易:其次它让具体的创建实例过程与客户端分 ...
- Spring课程 Spring入门篇 4-6 Spring bean装配之基于java的容器注解说明--@ImportResource和@Value java与properties文件交互
1 解析 1.1 这两个注解应用在什么地方 1.2 应用方式 1.3 xml方式实现取值 2 代码演练 2.1 @ImportResource和@Value代码演练 1 解析 1.1 这两个注解应用在 ...
- SQL语句执行与结果集的获取
title: SQL语句执行与结果集的获取 tags: [OLEDB, 数据库编程, VC++, 数据库] date: 2018-01-28 09:22:10 categories: windows ...
- Spring @Resource, @Autowired and @Inject 注入
Overview I’ve been asked several times to explain the difference between injecting Spring beans with ...
- 21_AOP_Advice增强2(异常、引介)
[异常抛出增强] 异常抛出异常最适合的应用场景:事务管理. 当参与事务的某个Dao发生异常时,事务管理器就必须回滚事务. [异常抛出增强 例子] [操作数据库的Dao类:PersonDao.java] ...