AC自动机模板题
AC自动机理解要点:
1)fail指针指向的是每个节点,在字典树上和这个节点后缀相同的最长单词,每次都这样匹配,必定不会漏过答案。
2)字典树建立后,会在bfs求fail阶段把字典树变成一个字典树图(不知道理解的对不对),就是把字典树的末尾节点再往下添加一层,并且连接到fail指针指向的相同位子的儿子。
两道模板题和AC代码。
#include<bits/stdc++.h>
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=;
char s[maxn],p[maxn];
int trie[maxn][],cntword[maxn],fail[maxn],cnt=;
int n;
void insert(char *s){
int root=;
int si=strlen(s);
for(int i=;i<si;i++)
{
int Next=s[i]-'a';
if(!trie[root][Next])trie[root][Next]=++cnt;
root=trie[root][Next];
}
cntword[root]++;
}
void getfail(){
queue<int >q;
for(int i=;i<;i++)
{
if(trie[][i]){
q.push(trie[][i]);
}
}
while(!q.empty())
{
int now=q.front();
q.pop();
for(int i=;i<;i++)
{
if(trie[now][i]){
fail[trie[now][i]]=trie[fail[now]][i];
q.push(trie[now][i]);
}else{
trie[now][i]=trie[fail[now]][i];
}
}
}
}
int query(char *s){
int now=,ans=;
int si=strlen(s);
for(int i=;i<si;i++)
{
now=trie[now][s[i]-'a'];
for(int j=now;j&&cntword[j]!=-;j=fail[j])
{
ans+=cntword[j];
cntword[j]=-;
}
}
return ans;
}
int main(){
cin>>n;
while(n--)
{
scanf("%s",p);
insert(p);
}
fail[]=;
getfail();
scanf("%s",s);
cout<<query(s)<<endl;
}
#include<bits/stdc++.h>
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=;
char s[maxn],p[maxn];
int trie[maxn][],cntword[maxn],fail[maxn],cnt=;
int n;
int num[maxn];
map<int,string>dio;
void insert(char *s){
int root=;
int si=strlen(s);
for(int i=;i<si;i++)
{
int Next=s[i]-'a';
if(!trie[root][Next])trie[root][Next]=++cnt;
root=trie[root][Next];
}
dio[root]=s;
cntword[root]++;
}
void getfail(){
queue<int >q;
for(int i=;i<;i++)
{
if(trie[][i]){
q.push(trie[][i]);
}
}
while(!q.empty())
{
int now=q.front();
q.pop();
for(int i=;i<;i++)
{
if(trie[now][i]){
fail[trie[now][i]]=trie[fail[now]][i];
q.push(trie[now][i]);
}else{
trie[now][i]=trie[fail[now]][i];
}
}
}
}
void query(char *s){
int now=,ans=;
int si=strlen(s);
for(int i=;i<si;i++)
{
now=trie[now][s[i]-'a'];
for(int j=now;j&&cntword[j]!=-;j=fail[j])
{
//ans+=cntword[j];
if(cntword[j]>){
num[j]+=cntword[j];
}
//cntword[j]=-1;
}
}
}
void init(){
clr(trie,);
clr(num,),clr(cntword,);
dio.clear();
}
int main(){
while(scanf("%d",&n),n){
init();
for(int i=;i<=n;i++)
{
scanf("%s",p);
insert(p);
}
int p,maxx=;
vector<int >ans;
fail[]=;
getfail();
scanf("%s",s);
query(s);
for(int i=;i<=cnt;i++)
{
if(num[i]>maxx){
maxx=num[i];
ans.clear();
ans.push_back(i);
}else if(num[i]==maxx)
{
ans.push_back(i);
}
}
cout<<maxx<<endl;
for(int i=;i<ans.size();i++)
{
cout<<dio[ans[i]]<<endl;
}
}
}
AC自动机模板题的更多相关文章
- HDU 2222 AC自动机模板题
题目: http://acm.hdu.edu.cn/showproblem.php?pid=2222 AC自动机模板题 我现在对AC自动机的理解还一般,就贴一下我参考学习的两篇博客的链接: http: ...
- HDU 3065 (AC自动机模板题)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3065 题目大意:多个模式串,范围是大写字母.匹配串的字符范围是(0~127).问匹配串中含有哪几种模 ...
- HDU 2896 (AC自动机模板题)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2896 题目大意:多个模式串.多个匹配串.其中串的字符范围是(0~127).问匹配串中含有哪几个模式串 ...
- HDU 2222(AC自动机模板题)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2222 题目大意:多个模式串.问匹配串中含有多少个模式串.注意模式串有重复,所以要累计重复结果. 解题 ...
- HDU3695(AC自动机模板题)
题意:给你n个字符串,再给你一个大的字符串A,问你着n个字符串在正的A和反的A里出现多少个? 其实就是AC自动机模板题啊( ╯□╰ ) 正着query一次再反着query一次就好了 /* gyt Li ...
- HDu-2896 病毒侵袭,AC自动机模板题!
病毒侵袭 模板题,不多说了.. 题意:n个不同的字符串分别代表病毒特征,给出m次查询,每次一个字符串(网址),求这个字符串中有几个病毒特征,分别从大到小输出编号,最后输出所有的带病毒网址个数.格式请看 ...
- [Bzoj3940] [AC自动机,USACO 2015 February Gold] Censor [AC自动机模板题]
AC自动机模板题(膜jcvb代码) #include <iostream> #include <algorithm> #include <cstdio> #incl ...
- HDU 2222 (AC自动机模板题)
题意: 给一个文本串和多个模式串,求文本串中一共出现多少次模式串 分析: ac自动机模板,关键是失配函数 #include <map> #include <set> #incl ...
- HDU-2222 Keywords Search(AC自动机--模板题)
题目大意:统计一共出现了多少次模板串. 题目分析:AC自动机的模板题.不过这题有坑,相同的模板串不能只算一次. 代码如下: # include<iostream> # include< ...
- HDU 2222 Keywords Search(AC自动机模板题)
http://acm.hdu.edu.cn/showproblem.php?pid=2222 题意:给出多个单词,最后再给出一个模式串,求在该模式串中包含了多少个单词. 思路: AC自动机的模板题. ...
随机推荐
- 协方差与pearson相关系数
协方差 协方差大于0,表示两个随机变量正线性相关 协方差等于0,表示两随机变量无线性相关 协方差小于0,表示两随机变量负线性相关 协方差智能表示随机变量的线性相关关系,不能刻画其相关程度. 因此引入了 ...
- 如何优雅地使用命令行设置windows文件关联
如何优雅地使用命令行设置windows文件关联 使用ftype查看帮助 设置关联所需命令有ftype assoc,需要管理员权限.如果忘记使用方法可通过ftype的帮助获取查看方法 C:\WINDOW ...
- Redis 数据库学习
安装(mac) 使用homebrew安装,命令是:brew install redis. 安装完成后启动命令:brew services start redis. 使用命令redis-cli进入red ...
- 【Android学习】Service&Boradcast初步
Service初步 掌握Service概念 掌握Service分类 Service开发能力具备 了解Service和intentService类的区别 重点难点 StartService和BoundS ...
- Gym 100989L (DFS)
AbdelKader enjoys math. He feels very frustrated whenever he sees an incorrect equation and so he tr ...
- hdu2579之BFS
Dating with girls(2) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
- vs项目属性中的包含目录和库目录以及附加依赖项全都配置正确了,却还是提示:无法解析的外部符号
这种情况下,很大可能是lib文件有问题 我是用vs编译下载的源代码文件得到的lib出现了如题的情况, 后来去网站上直接下载了lib文件,竟然解决了!-.-
- IOS 6 自动布局 入门
http://blog.csdn.net/itianyi/article/details/8535392
- BlockingCollection 集合随记
BlockingCollection 集合是一个并发安全的集合,而且设计用来实现类似于消息队列的功能,生产者.消费者模式. static void Main(string[] args) { Bloc ...
- C# winform 自定义鼠标光标
第一种:(调用系统API)首先引入两个命名空间代码如下: using System.Runtime.InteropServices;using System.Reflection;导入API代码如下: ...