UESTC1977-图书馆(AC自动机应用)
M - 图书馆
Time Limit: 2000 MS Memory Limit: 256 MB
电子科技太学图书馆创建于1956年,馆舍总面积66974平方米,各类阅览室37个,阅览座位10023个(含在建新馆),馆藏总量371.8万册。
为了更好地管理数量如此庞大的书籍,管理员准备对所有书籍进行一次统计、整理。图书管理员需要将相似的图书归为一类,为此它为每个分类选出了几个关键词,如果在一本书的文本中,关键词出现得越频繁,则说明这本书越有可能属于这一类。
现在,管理员把这项重任交给你,并希望在太阳完全下山之前能够统计出每个关键词在书本中出现次数的总和。
注:重复关键词重复统计。
Input
输入文件中第一行一个正整数 TT 表示测试数据组数。
每组测试数据第一行为书籍内容,为长度不大于 1000000 的字符串 SS。
第二行为不多于 10000 的整数 NN ,表示关键词个数,接下去 NN 行,每行有长度不超过 50 的关键词字符串。
数据保证字符串只由英文小写字母 a-z 组成,不存在空串。 T×|S|≤10000000T×|S|≤10000000
Output
每组测试数据输出一行,为每个关键词在书本中出现次数的总和。
Sample input and output
| Sample Input | Sample Output |
|---|---|
1 |
3 |
Hint
trumpet 中出现了 trump pet rump 。
AC自动机模版题:
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#define MAXNODE 500005
using namespace std;
int n,T;
char str[1000005],s[100];
struct ACautomata
{
int ch[MAXNODE][26];
int f[MAXNODE]; // fail函数
int val[MAXNODE]; // 是否为单词结尾
int last[MAXNODE]; // 后缀链接
int cnt[10005]; // 每个单词出现次数
int tot; // trie 单词总数
int num; // 单词出现了几个
int time[10005]; //以val[i]结尾的单词数量
void init()
{
num = 0;
tot = 1;
memset(ch[0],0,sizeof(ch[0]));
memset(cnt,0,sizeof(cnt));
memset(time,0,sizeof(time));
}
int idx(char c) //获取编号
{
return c - 'a';
}
void insert(char *s,int v) //插入
{
int u = 0,n = strlen(s);
for(int i = 0;i < n;i++)
{
int c = idx(s[i]);
if(!ch[u][c])
{
memset(ch[tot],0,sizeof(ch[tot]));
val[tot] = 0;
ch[u][c] = tot++;
}
u = ch[u][c];
}
if(val[u]) time[val[u]]++;
else val[u] = v,time[v] = 1;
}
void print(int j)
{
if(j)
{
//if(!cnt[val[j]])
num += time[val[j]];
cnt[val[j]]++;
print(last[j]);
}
}
void find(char *T)
{
int n = strlen(T);
int j = 0;
for(int i = 0;i < n;i++)
{
int c = idx(T[i]);
j = ch[j][c];
if(val[j]) print(j);
else if(last[j]) print(last[j]);
}
}
void getFail()
{
queue<int> q;
f[0] = 0;
for(int c = 0;c < 26;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 < 26;c++)
{
int u = ch[r][c];
if(!u)
{
ch[r][c] = ch[f[r]][c];
continue;
}
q.push(u);
f[u] = ch[f[r]][c];
last[u] = val[f[u]] ? f[u] : last[f[u]];
}
}
}
} tree;
int main()
{
cin>>T;
while(T--)
{
tree.init();
scanf("%s",str);
cin>>n;
for(int i = 1;i <= n;i++)
{
scanf("%s",s);
tree.insert(s,i);
}
tree.getFail();
tree.find(str);
cout<<tree.num<<endl;
}
return 0;
}
UESTC1977-图书馆(AC自动机应用)的更多相关文章
- 一个在开源中国博客上讲解的AC自动机
原文出处:http://my.oschina.net/amince/blog/196426 原 荐 AC(Aho—Corasiek) 多模式匹配算法 摘要 如何在一篇文章中,搜索多个关键字,如何快速查 ...
- 基于trie树做一个ac自动机
基于trie树做一个ac自动机 #!/usr/bin/python # -*- coding: utf-8 -*- class Node: def __init__(self): self.value ...
- AC自动机-算法详解
What's Aho-Corasick automaton? 一种多模式串匹配算法,该算法在1975年产生于贝尔实验室,是著名的多模式匹配算法之一. 简单的说,KMP用来在一篇文章中匹配一个模式串:但 ...
- python爬虫学习(11) —— 也写个AC自动机
0. 写在前面 本文记录了一个AC自动机的诞生! 之前看过有人用C++写过AC自动机,也有用C#写的,还有一个用nodejs写的.. C# 逆袭--自制日刷千题的AC自动机攻克HDU OJ HDU 自 ...
- BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2545 Solved: 1419[Submit][Sta ...
- BZOJ 3172: [Tjoi2013]单词 [AC自动机 Fail树]
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 3198 Solved: 1532[Submit][Status ...
- BZOJ 1212: [HNOI2004]L语言 [AC自动机 DP]
1212: [HNOI2004]L语言 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1367 Solved: 598[Submit][Status ...
- [AC自动机]【学习笔记】
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)To ...
- AC自动机 HDU 3065
大概就是裸的AC自动机了 #include<stdio.h> #include<algorithm> #include<string.h> #include< ...
随机推荐
- 【转载】常见十大经典排序算法及C语言实现【附动图图解】
原文链接:https://www.cnblogs.com/onepixel/p/7674659.html 注意: 原文中的算法实现都是基于JS,本文全部修改为C实现,并且统一排序接口,另外增加了一些描 ...
- jdk8 函数式编程概念
yls 2019/11/7 函数式接口 如果一个接口只有一个抽象方法,那么该接口就是函数式接口 如果我们在某接口上声明了FunctionalInterface注解,那么编译器就会按照函数式接口的定义来 ...
- PHP 中四大经典排序算法
1.冒泡排序 在要排序的一组数中,对当前还未排好的序列,从前往后对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒.即,每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换. ...
- python的模块future用法实例解析
计算机的知识太多了,很多东西就是一个使用过程中详细积累的过程.最近遇到了一个很久关于future的问题,踩了坑,这里就做个笔记,免得后续再犯类似错误. future的作用:把下一个新版本的特性导入 ...
- MySQL 5.7 - 通过 BINLOG 恢复数据
日常开发,运维中,经常会出现误删数据的情况.误删数据的类型大致可分为以下几类: 使用 delete 误删行 使用 drop table 或 truncate table 误删表 使用 drop dat ...
- Obtaining the backtrace - libunwind
Sometimes when working on a large project, I find it useful to figure out all the places from which ...
- Matplotlib入门简介
Matplotlib是一个用Python实现的绘图库.现在很多机器学习,深度学习教学资料中都用它来绘制函数图形.在学习算法过程中,Matplotlib是一个非常趁手的工具. 一般概念 图形(figur ...
- Centos下安装PHP ldap扩展
Centos下安装PHP ldap扩展,有两种方法,仅供参考. 一.在线安装 执行下面命令: 1 yum install PHP-ldap 可能出现的问题: Error: php70w-common- ...
- Flow入门初识
Flow是facebook出品的JavaScript静态类型检查工具. 由于JavaScript是动态类型语言,它的灵活性也会造成一些代码隐患,使用Flow可以在编译期尽早发现由类型错误引起的bug, ...
- salesforce lightning零基础学习(十六) 公用组件之 获取字段label信息
我们做的项目好多都是多语言的项目,针对不同国家需要展示不同的语言的标题.我们在classic中的VF page可谓是得心应手,因为系统中已经封装好了我们可以直接在VF获取label/api name等 ...