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< ...
随机推荐
- Genymotion模拟器安装搜狗输入法
Genymotion模拟器默认没有中文输入法,如果在一些调试中涉及到需要输入中文则必须需要安装中文输入法. 这里以搜狗输入法为例. 这里需要注意一下几点就行: 百度下载一个搜狗输入法,需要特别注意的是 ...
- c#控制台玩飞行棋游戏
using System; namespace Game{ class Program { //用静态字段模拟全局变量 public static int[] Maps = new int[100]; ...
- gRPC asp.net core自定义策略认证
在GitHub上有个项目,本来是作为自己研究学习.net core的Demo,没想到很多同学在看,还给了很多星,所以觉得应该升成3.0,整理一下,写成博分享给学习.net core的同学们. 项目名称 ...
- 学习记录:《C++设计模式——李建忠主讲》6.“状态变化”模式
状态变化模式:在组件构建过程中,某些对象的状态经常面临变化,如何对这些变化进行有效的管理?同时又维持高层模块的稳定.状态变化模式为这一问题提供了一种解决方案. 典型模式:状态模式(State).备忘录 ...
- LVM扩容案例
LVM基础命令: pvdisplay 查看检查pv pvremove /dev/sdb #清除一个pv fdisk -l 检查磁盘 df -h 检查全部磁盘大小 df -Th 检查磁盘大小和分区格式类 ...
- Oracle数据库 获取CLOB字段存储的xml格式字符串指定节点的值
参照: Oracle存储过程中使用游标来批量解析CLOB字段里面的xml字符串 背景:在写存储过程时,需要获取表单提交的信息.表单信息是以xml格式的字符串存储在colb类型的字段dataxml中,如 ...
- ansible start canal
- name: Start canal server shell: source /etc/profile && nohup /opt/canal/bin/startup.sh
- 根据本地ip获取地理位置,再根据地理位置,获取天气
import json,requestsfrom urllib.request import urlopenfrom pyquery import PyQuery as pqfrom lxml imp ...
- python3 之 趣味数学题(爱因斯坦)
爱因斯坦曾出过这样一道有趣的数学题: 有一个长阶梯,若每步上 2 阶,最 后剩 1 阶; 若每步上 3 阶,最后剩 2 阶; 若每步上 5 阶,最后剩 4 阶; 若每步上 6 阶,最后剩 5 阶; 只 ...
- 【集训Day3 离散化】矩形覆盖
矩形覆盖(planting) [问题描述] 给定在一个平面坐标系上的N(1 <= N <= 100)个矩形区域,这N个矩形可能有相互覆盖的部分.求平面上被所有矩形覆盖的总面积,重复部分只算 ...