AC自动机学习博客

  AC自动机理解要点:

    1)fail指针指向的是每个节点,在字典树上和这个节点后缀相同的最长单词,每次都这样匹配,必定不会漏过答案。

    2)字典树建立后,会在bfs求fail阶段把字典树变成一个字典树图(不知道理解的对不对),就是把字典树的末尾节点再往下添加一层,并且连接到fail指针指向的相同位子的儿子。

   两道模板题和AC代码。

P3808

#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;
}

P3796

#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自动机模板题的更多相关文章

  1. HDU 2222 AC自动机模板题

    题目: http://acm.hdu.edu.cn/showproblem.php?pid=2222 AC自动机模板题 我现在对AC自动机的理解还一般,就贴一下我参考学习的两篇博客的链接: http: ...

  2. HDU 3065 (AC自动机模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3065 题目大意:多个模式串,范围是大写字母.匹配串的字符范围是(0~127).问匹配串中含有哪几种模 ...

  3. HDU 2896 (AC自动机模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2896 题目大意:多个模式串.多个匹配串.其中串的字符范围是(0~127).问匹配串中含有哪几个模式串 ...

  4. HDU 2222(AC自动机模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2222 题目大意:多个模式串.问匹配串中含有多少个模式串.注意模式串有重复,所以要累计重复结果. 解题 ...

  5. HDU3695(AC自动机模板题)

    题意:给你n个字符串,再给你一个大的字符串A,问你着n个字符串在正的A和反的A里出现多少个? 其实就是AC自动机模板题啊( ╯□╰ ) 正着query一次再反着query一次就好了 /* gyt Li ...

  6. HDu-2896 病毒侵袭,AC自动机模板题!

    病毒侵袭 模板题,不多说了.. 题意:n个不同的字符串分别代表病毒特征,给出m次查询,每次一个字符串(网址),求这个字符串中有几个病毒特征,分别从大到小输出编号,最后输出所有的带病毒网址个数.格式请看 ...

  7. [Bzoj3940] [AC自动机,USACO 2015 February Gold] Censor [AC自动机模板题]

    AC自动机模板题(膜jcvb代码) #include <iostream> #include <algorithm> #include <cstdio> #incl ...

  8. HDU 2222 (AC自动机模板题)

    题意: 给一个文本串和多个模式串,求文本串中一共出现多少次模式串 分析: ac自动机模板,关键是失配函数 #include <map> #include <set> #incl ...

  9. HDU-2222 Keywords Search(AC自动机--模板题)

    题目大意:统计一共出现了多少次模板串. 题目分析:AC自动机的模板题.不过这题有坑,相同的模板串不能只算一次. 代码如下: # include<iostream> # include< ...

  10. HDU 2222 Keywords Search(AC自动机模板题)

    http://acm.hdu.edu.cn/showproblem.php?pid=2222 题意:给出多个单词,最后再给出一个模式串,求在该模式串中包含了多少个单词. 思路: AC自动机的模板题. ...

随机推荐

  1. Notepad++ xml/json格式化

    Xml格式化: 1. 安装XML Tools插件 (1) 通过网址http://sourceforge.net/projects/npp-plugins/files/XML%20Tools/下载XML ...

  2. Oracle——约束

    NOT NULLUNIQUE PRIMARY KEYFOREIGN KEYCHECK 如果不指定约束名 ,Oracle server 自动按照 SYS_Cn 的格式指定约束名 --指定约束名 CREA ...

  3. springmvc乱码配置

    web.xml配置 <!-- springmvc乱码 --> <filter> <filter-name>encodingFilter</filter-nam ...

  4. CodeForces 288C Polo the Penguin and XOR operation (位运算,异或)

    题意:给一个数 n,让你求一个排列,使得这个排列与0-n的对应数的异或之最大. 析:既然是异或就得考虑异或的用法,然后想怎么才是最大呢,如果两个数二进制数正好互补,不就最大了么,比如,一个数是100, ...

  5. MSSQLServer 存储过程

    一直对存储过程懵懵懂懂,翻了资料,觉得存储过程大有用处. 1.改善性能 SQL语句的执行需要先编译在执行,存储过程就是一组为了完成特定功能的SQL语句集,他可以一次编译,下次执行不再编译,提高运行效率 ...

  6. C# 释放资源的规范写法

    static class CSharp_3 { /* ---------------------------------------- * 以下学习资源的释放:IDispose和析构函数 * 1.ID ...

  7. Android 文件存放路径【转】

    对于应用携带的静态数据,可以放置在应用的assets目录或者res,raw目录下.对于assets目录下的静态数据,存在当文件最大支持1MB的局限,读取方式如下: 1 InputStream is = ...

  8. 初涉Runtime (一)

    Objective-C 是一门动态语言,有很多东西都是运行时才确定的. 比如这句代码首先声明testObject是一个NSString,然后创建了一个NSData对象,并且将这个对象的内存地址保存在t ...

  9. c语言和java以及安卓和苹果

    苹果手机是本地,没有中间环节,速度快,基于Linux系统 安卓是通过虚拟机,影响速度 就像c语言和java c适用于架构小的地方,因为直接编译运行 而java用于架构比较大的地方,启动慢,启动之后效率 ...

  10. Application.DoEvent和定时刷新控件

    我们写一个textbox,让其依循环递增,但每次都会出现假死现象,等循环结束后,变为最终值.今天总结一下: private void button3_Click(object sender, Even ...