题意:给出一些单词,求多少个单词在字符串中出现过(单词表单词可能有相同的,这些相同的单词视为不同的分别计数)(如果单词x在字符串中出现一次而在单词表中有两个则ans+2,在字符串中出现两次而单词表中有一个则ans+1)
AC自动机模板题,之前学了总觉得不扎实,现在有底了现在终于可以去敲心头大恨,兴奋!!!
代码
 #include<cstdio>
#include<cstring>
const int maxn=;
const double eps=1e-;
const long long modn=;
int n;
char a[]={};
char b[*maxn]={};
struct trie{
int next[];
bool exist;
int count;
int fail;
}e[maxn*]={};
int tot,ans;
int q[maxn*]={}; void init(int x,int k,int j){
if(j>k){
e[x].exist=;
e[x].count++;
return;
}
int z=a[j]-'a';
if(!e[x].next[z])
e[x].next[z]=++tot;
init(e[x].next[z],k,j+);
}
void fir(){
memset(e,,sizeof(e)); memset(q,,sizeof(q));
tot=ans=;
}
void doit(){
int head=,tail=,x,y,f;
q[]=;
while(head<=tail){
x=q[head++];
for(int i=;i<;i++){
if(e[x].next[i]){
y=e[x].next[i];
if(x!=){
f=e[x].fail;
while((!e[f].next[i]) && f )
f=e[f].fail;
e[y].fail=e[f].next[i];
}q[++tail]=y;
}
}
}
}
void find(){
scanf("%s",&b);
int k=std::strlen(b);
int x=,z,y;
for(int i=;i<k;i++){
z=b[i]-'a';
while( (!e[x].next[z])&& x){
x=e[x].fail;
}x=e[x].next[z]; y=x;
while(y&&e[y].count){
ans+=e[y].count;
e[y].count=;
y=e[y].fail;
}
}
}
int main(){
int T;scanf("%d",&T);
while(T-->){
fir();
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%s",&a);
init(,std::strlen(a)-,);
}
doit();
find();
printf("%d\n",ans);
}
return ;
}

更新:

整理模板的时候发现自己原来的代码有问题。这个新版本应该没问题了。

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
const int maxn=;
int n,siz;
char ch[]={};
char str[maxn*]={};
struct trie{
int sig[];
int cnt;
int vis;
int fail;
}t[maxn*];int tot=;
int q[maxn*]={};int head=,tail=;
void fir(){
tot=;memset(t,,sizeof(t));//memset(q,0,sizeof(q));
}
void init(int x,int j){
if(j>siz-){ t[x].cnt++; return; }
int z=ch[j]-'a';
if(!t[x].sig[z])t[x].sig[z]=++tot;
init(t[x].sig[z],j+);
}
void build_fail(){
int head=,tail=,x,y,f;q[]=;
while(head<=tail){
x=q[head++];
for(int i=;i<;i++)
if(t[x].sig[i]){
y=t[x].sig[i];
if(x){
f=t[x].fail;
while((!t[f].sig[i])&&f)
f=t[f].fail;
t[y].fail=t[f].sig[i];
}q[++tail]=y;
}
}
}
int get_num(){//字符串中包含的单词数量,重复的不记录,
//如果单词x在字符串中出现一次而在单词表中有两个则ans+2
//在字符串中出现两次而单词表中有一个则ans+1
int ans=,x=,y,z;
for(int i=;i<siz;i++){
z=str[i]-'a';
while((!t[x].sig[z])&&x)
x=t[x].fail;
x=t[x].sig[z];y=x;
while(y&&(!t[y].vis)){//保证了每个结尾只访问一次
ans+=t[y].cnt;
t[y].vis=;t[y].cnt=;
y=t[y].fail;
}
}
return ans;
}
int main(){
int T;scanf("%d",&T);
while(T-->){
fir();
scanf("%d",&n);
for(int i=;i<=n;i++){scanf("%s",ch);siz=strlen(ch);init(,);}
build_fail();
scanf("%s",str);siz=strlen(str);
printf("%d\n",get_num());
}
return ;
}

new

POJ2222 Keywords Search AC自动机模板的更多相关文章

  1. Keywords Search(AC自动机模板)

    Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others ...

  2. Match:Keywords Search(AC自动机模板)(HDU 2222)

    多模匹配 题目大意:给定很多个字串A,B,C,D,E....,然后再给你目标串str字串,看目标串中出现多少个给定的字串. 经典AC自动机模板题,不多说. #include <iostream& ...

  3. hdu 2222 Keywords Search ac自动机模板

    题目链接 先整理一发ac自动机模板.. #include <iostream> #include <vector> #include <cstdio> #inclu ...

  4. HDU2222 Keywords Search [AC自动机模板]

    Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others ...

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

    学习AC自动机请戳这里:大神blog........ 自动机的模板: #include <iostream> #include <algorithm> #include < ...

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

    <题目链接> 题目大意: 给你一些单词,和一个字符串,问你这个字符串中含有多少个上面的单词. 解题分析: 这是多模匹配问题,如果用KMP的话,对每一个单词,都跑一遍KMP,那么当单词数量非 ...

  7. 【HDU 2222】Keywords Search AC自动机模板题

    参考iwtwiioi的模板写出来的.上午gty讲的并没有听懂,只好自己慢慢对着模板理解. 在HDU上为什么相同的程序提交有时T有时A!!! 奉上sth神犇的模板(不是这道题): var ch:char ...

  8. [hdu2222] [AC自动机模板] Keywords Search [AC自动机]

    AC自动机模板,注意!ch,Fail,lab数组的大小不是n而是节点个数,需要认真计算! #include <iostream> #include <algorithm> #i ...

  9. 【HDU2222】Keywords Search AC自动机

    [HDU2222]Keywords Search Problem Description In the modern time, Search engine came into the life of ...

随机推荐

  1. 【BZOJ】4316: 小C的独立集 静态仙人掌

    [题意]给定仙人掌图,求最大独立集(选择最大的点集使得点间无连边).n<=50000,m<=60000. [算法]DFS处理仙人掌图 [题解]参考:[BZOJ]1023: [SHOI200 ...

  2. cookie、localstroage与sessionstroage的一些优缺点

    1.    Cookie 在前端开发中,尽量少用cooie,原因: (1)   cookie限制大小,约4k左右,不适合存储业务数据,尤其是数据量较大的值: (2)   cookie会每次随http请 ...

  3. 4-Python数据类型之元组-字符串

    目录 1 元组概念 1.1 元祖的特点 1.2 元组的定义 1.3 元组的访问 1.4 元组的查询 2 命名元组 3 字符串 3.1 字符串的基本操作 3.1.1 字符串的访问 3.1.2 字符串的拼 ...

  4. 用ELK搭建简单的日志收集分析系统【转】

    缘起 在微服务开发过程中,一般都会利用多台服务器做分布式部署,如何能够把分散在各个服务器中的日志归集起来做分析处理,是一个微服务服务需要考虑的一个因素. 搭建一个日志系统 搭建一个日志系统需要考虑一下 ...

  5. VC RichEdit中英文关键字标红

    最近需要做vc的RichEdit控件里的内容关键字标红,由于RichEdit的内容可能是中英文混合的,所以需要先转成Unicode,再用wcsstr函数找到关键字出现的位置,再用SetSel.SelS ...

  6. C++ 模版的优点和缺点

    优点: 1. 灵活性, 可重用性和可扩展性; 2. 可以大大减少开发时间,模板可以把用同一个算法去适用于不同类型数据,在编译时确定具体的数据类型; 3. 模版模拟多态要比C++类继承实现多态效率要高, ...

  7. ubuntu上安装MySQL详解

     1. 安装 在终端输入 sudo apt-get install mysql-server mysql-client 回车 2.安装完成后检测MySQL的状态 systemctl status my ...

  8. ActiveMQ-如何使用JMS API?

    JMS编程模型 JMS定义了Java中访问消息中间件的一组接口,主要包括ConnectionFactory.Connection.Session.Destination.MessageProducer ...

  9. deep learning 资源汇总

    不定时更新..... 首先是吴老爷子在优酷的视频,可惜外音太大了:http://list.youku.com/albumlist/show?id=21508721&ascending=1&am ...

  10. HDU 4370 0 or 1(spfa+思维建图+计算最小环)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4370 题目大意:有一个n*n的矩阵Cij(1<=i,j<=n),要找到矩阵Xij(i< ...