P3808 【模版】AC自动机(简单版)
题目背景
这是一道简单的AC自动机模版题。
用于检测正确性以及算法常数。
为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交。
题目描述
给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过。
输入输出格式
输入格式:
第一行一个n,表示模式串个数;
下面n行每行一个模式串;
下面一行一个文本串。
输出格式:
一个数表示答案
输入输出样例
2
a
aa
aa
2
说明
subtask1[50pts]:∑length(模式串)<=10^6,length(文本串)<=10^6,n=1;
subtask2[50pts]:∑length(模式串)<=10^6,length(文本串)<=10^6;
也是模板,没什么么好说的,
只不过每次更新的时候是++,而不是=1!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
#include<map>
using namespace std;
const int MAXN=;
void read(int &n)
{
char c='+';int x=;bool flag=;
while(c<''||c>''){c=getchar();if(c=='-')flag=;}
while(c>=''&&c<=''){x=x*+c-;c=getchar();}
flag==?n=-x:n=x;
}
char s[MAXN];
char text[MAXN];
int n;
int ans=;
struct AC_Automata
{
int sz;
int ch[MAXN][];//trie树
int val[MAXN];// 记录是否有单词
int last[MAXN];
int f[MAXN];
int sigma_sz;
void Init()
{
memset(ch[],,sizeof(ch[]));
sz=;
sigma_sz=;
}
int idx(char c)
{
return c-'a';
}
void Insert(char *s,int pos)
{
int l=strlen(s); int now=;
for(int i=;i<l;i++)
{
int c=idx(s[i]);
if(!ch[now][c])
{
memset(ch[sz],,sizeof(ch[sz]));
val[sz]=;
ch[now][c]=sz++;
}
now=ch[now][c];
}
val[now]++;//一个单词的结束
}
void getfail()
{
f[]=;
queue<int>q;
for(int i=;i<sigma_sz;i++)
{
int u=ch[][i];
if(u)// 此处有单词出现
{
f[u]=;// 连向根节点
q.push(u);
last[u]=;// 上一个出现的单词一定是根节点
// 上面两条语句没什么卵用,只是为了帮助理解AC自动机的含义
}
}
while(!q.empty())
{
int p=q.front();q.pop();
for(int i=;i<sigma_sz;i++)
{
int u=ch[p][i];
if(!u)//没有孩子
{
ch[p][i]=ch[f[p]][i];// 补上一条不存在的边,减少查找次数
continue;
}
q.push(u);
int v=f[p];// 找到它的失陪指针
f[u]=ch[v][i];//因为我们在上面补上了一条不存在边,所以他一定存在孩子
last[u]=val[f[u]] ? f[u] : last[f[u]];
//判断下是不是单词结尾 是, 不是
}
}
}
int ok(int pos)
{
if(val[pos])
{
ans+=val[pos];
val[pos]=;
ok(last[pos]);
}
}
void find(char *s)// 查找模式串
{
int l=strlen(s);
int j=;// 当前节点的编号
for(int i=;i<l;i++)
{
int c=idx(s[i]);
while(j&&!ch[j][c])
j=f[j];// 顺着失配边走
j=ch[j][c]; // 取到儿子
if(val[j])
ok(j);// 找到一个单词
else if(last[j])
ok(last[j]);// 当前节点不行就看看上一个单词出现的位置行不行
}
}
}ac;
int main()
{
scanf("%d",&n);
ac.Init();
for(int i=;i<=n;i++)
{
scanf("%s",s);
ac.Insert(s,i);
}
ac.getfail();
scanf("%s",text);
ac.find(text);
printf("%d\n",ans);
return ;
}
P3808 【模版】AC自动机(简单版)的更多相关文章
- [模板][P3808]AC自动机(简单版)
Description: 求n个模式串中有几个在文本串中出现 Solution: 模板,详见代码: #include<bits/stdc++.h> using namespace std; ...
- [算法模版]AC自动机
[算法模版]AC自动机 基础内容 板子不再赘述,OI-WIKI有详细讲解. \(query\)函数则是遍历文本串的所有位置,在文本串的每个位置都沿着\(fail\)跳到根,将沿途所有元素答案++.意义 ...
- 洛谷P3808 & P3796 AC自动机模板
题目:P3808:https://www.luogu.org/problemnew/show/P3808 P3796:https://www.luogu.org/problemnew/show/P37 ...
- Ring HDU - 2296 AC自动机+简单DP和恶心的方案输出
题意: 就是现在给出m个串,每个串都有一个权值,现在你要找到一个长度不超过n的字符串, 其中之前的m个串每出现一次就算一次那个字符串的权值, 求能找到的最大权值的字符串,如果存在多个解,输出最短的字典 ...
- POJ 1625 Censored!(AC自动机->指针版+DP+大数)题解
题目:给你n个字母,p个模式串,要你写一个长度为m的串,要求这个串不能包含模式串,问你这样的串最多能写几个 思路:dp+AC自动机应该能看出来,万万没想到这题还要加大数...orz 状态转移方程dp[ ...
- 小明系列故事――女友的考验 HDU - 4511 AC自动机+简单DP
题意:自己看题目,中文体面. 题解: 把所有不能走的路径放入AC自动机中. 然后DP[i][j]表示走到 i 这个点,且位于AC自动机 j 这个节点最短距离 然后直接DP即可.注意一点会爆int #i ...
- Walk Through Squares HDU - 4758 AC自动机+简单状压DP
题意:给你两个串,求用m个R,n个D能组成多少个包含这两个串 题解:先构造一个AC自动机记录每个状态包含两个串的状态, 状态很容易定义 dp[i][j][k][status]表示在AC自动机K这个节点 ...
- Censored! - POJ 1625(ac自动机+简单dp+高精度运算)
题目大意:首先给一个字符集合,这个集合有N个字符,然后需要一个长度为M的句子,但是据子里面不能包含的串有P个,每个串里面的字符都是有字符集和里面的字符构成的,现在想知道最多能构造多少个不重复的句子. ...
- AC自动机例题
P3808 [模板]AC自动机(简单版) [题目描述] 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. #include<bits/stdc++.h> using name ...
- 【AC自动机】AC自动机
Definition & Solution AC自动机是一种多模式串的字符串匹配数据结构,核心在于利用 fail 指针在失配时将节点跳转到当前节点代表字符串的最长后缀子串. 首先对 模式串 建 ...
随机推荐
- Axure RP 9 WIN10 64位安装步骤及注册码
License栏输入:ABC Key栏输入:M5PHzBHvhAG3cNRr2CFxAJaIHaXOkwleDSctQ9sY0pQ2vd7eJzoBNtD7zBZNSPmT http://www.zh ...
- pytorch实战(7)-----卷积神经网络
一.卷积: 卷积在 pytorch 中有两种方式: [实际使用中基本都使用 nn.Conv2d() 这种形式] 一种是 torch.nn.Conv2d(), 一种是 torch.nn.function ...
- 洛谷 P2341 BZOJ 1051 [HAOI2006]受欢迎的牛
题目描述 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之间的“喜欢”是可以传递的——如果A喜 欢B,B喜欢C,那么A也喜欢C ...
- 转载 - KMP算法祥解
出处:http://www.cppblog.com/oosky/archive/2006/07/06/9486.html KMP字符串模式匹配详解 来自CSDN A_B_C_ABC 网友 KM ...
- EL表达式无法被解析
刚困死了,但是手上还在debug一个东西.然后就发现
- LeetCode之RemoveElement
题目: Given an array and a value, remove all instances of that value in place and return the new lengt ...
- iOS开发——定制圆形头像与照相机图库的使用
如今的App都很流行圆形的头像,比方QQ右上角的头像,今日头条的头像等等.这已经成为App设计的趋势了.今天我们就来简单实现一下这个功能,我还会把从手机拍照中或者图库中取出作为头像的照片存储到应用程序 ...
- Mybatis结合Spring注解自己主动扫描源代码分析
作为一个想做架构师的程序猿,必须是一个优秀的程序猿.在引入某一个框架的时候,必需要研究源代码,将新的开源框架的风险变为可控性. 1.Spring结合Mybatis最经常使用的配置. <!--理论 ...
- mysql选择上一条、下一条数据记录,排序上移、下移、置顶
1.功能须要 完毕列表排序上移,下移,置顶功能.效果例如以下图所看到的: 2设置思路 设置一个rank为之间戳,通过选择上移,就是将本记录与上一条记录rank值交换,下移就是将本条记录与下一条记录ra ...
- POJ 3723 Tree(树链剖分)
POJ 3237 Tree 题目链接 就多一个取负操作,所以线段树结点就把最大和最小值存下来,每次取负的时候,最大和最小值取负后.交换就可以 代码: #include <cstdio> # ...