POJ2222 Keywords Search 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自动机模板的更多相关文章
- Keywords Search(AC自动机模板)
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- Match:Keywords Search(AC自动机模板)(HDU 2222)
多模匹配 题目大意:给定很多个字串A,B,C,D,E....,然后再给你目标串str字串,看目标串中出现多少个给定的字串. 经典AC自动机模板题,不多说. #include <iostream& ...
- hdu 2222 Keywords Search ac自动机模板
题目链接 先整理一发ac自动机模板.. #include <iostream> #include <vector> #include <cstdio> #inclu ...
- HDU2222 Keywords Search [AC自动机模板]
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- HDU 2222 Keywords Search(AC自动机模板题)
学习AC自动机请戳这里:大神blog........ 自动机的模板: #include <iostream> #include <algorithm> #include < ...
- HDU 2222 Keywords Search (AC自动机)(模板题)
<题目链接> 题目大意: 给你一些单词,和一个字符串,问你这个字符串中含有多少个上面的单词. 解题分析: 这是多模匹配问题,如果用KMP的话,对每一个单词,都跑一遍KMP,那么当单词数量非 ...
- 【HDU 2222】Keywords Search AC自动机模板题
参考iwtwiioi的模板写出来的.上午gty讲的并没有听懂,只好自己慢慢对着模板理解. 在HDU上为什么相同的程序提交有时T有时A!!! 奉上sth神犇的模板(不是这道题): var ch:char ...
- [hdu2222] [AC自动机模板] Keywords Search [AC自动机]
AC自动机模板,注意!ch,Fail,lab数组的大小不是n而是节点个数,需要认真计算! #include <iostream> #include <algorithm> #i ...
- 【HDU2222】Keywords Search AC自动机
[HDU2222]Keywords Search Problem Description In the modern time, Search engine came into the life of ...
随机推荐
- 【洛谷 P2604】 [ZJOI2010]网络扩容(最大流,费用流)
题目链接 第一问就是简单的最大流. 第二问,保留第一问求完最大流的残量网络. 然后新建一个源点,向原源点连一条流量为k,费用为0的边. 然后所有边重新连一起(原来的边保留),费用为题目所给,最小费用即 ...
- 消息队列ActiveMQ的使用详解
通过上一篇文章 <消息队列深入解析>,我们已经消息队列是什么.使用消息队列的好处以及常见消息队列的简单介绍. 这一篇文章,主要带大家详细了解一下消息队列ActiveMQ的使用. 学习消息队 ...
- 首次成功的web渗透
web渗透 今天给大家讲一个最近做的一件令我振奋的一件事情 渗透培训刚刚结束的第二天 我在公网上挖到了我人生中的第一个站 总体来说个人真的很振奋人心 这个网站还没有进行更改但我已经通知了他们 ...
- ldconfig是一个动态链接库管理命令
ldconfig是一个动态链接库管理命令 为了让动态链接库为系统所共享,还需运行动态链接库的管理命令--ldconfig ldconfig 命令的用途,主要是在默认搜寻目录(/lib和/usr/li ...
- linux系统磁盘挂载
1.查看系统磁盘挂载情况 fdisk -l 2.格式化磁盘 mkfs -t ext3 /dev/sdb 3.挂在磁盘 mount /dev/sdb /disk2 4.查看磁盘挂载情况 df -h 5. ...
- Caused by: android.content.res.Resources$NotFoundException: Resource ID #0x7f070058 android-studio 3.0 from canary 5 to canary 6
我升级android-studio到了3.0 canary 6打包编译安装出现如下错误: 07-11 13:00:39.523 8913-8913/dcpl.com.myapplication E/A ...
- Feign 发送对象,对象含多个文件
Feign在发送文件时,可以使用Feign-form. 另一种方式,关键就是,要将文件转成Resource,然后使用Spring的MultivalueMap 本次发送的是个对象,对象里含有 文件对象数 ...
- python是如何进行内存管理的?
Python内存管理机制 Python内存管理机制主要包括以下三个方面: 引用计数机制 垃圾回收机制 内存池机制 引用计数 举个例子说明引用是什么: 1 如上为一个简单的赋值语句,1就是对象,a就是引 ...
- 欧拉回路&欧拉通路判断
欧拉回路:图G,若存在一条路,经过G中每条边有且仅有一次,称这条路为欧拉路,如果存在一条回路经过G每条边有且仅有一次, 称这条回路为欧拉回路.具有欧拉回路的图成为欧拉图. 判断欧拉通路是否存在的方法 ...
- js写一个插件
//;分号开头,用于防止代码压缩合并时与其它代码混在一起造成语法错误 //而事实证明,uglify压缩工具会将无意义的前置分号去掉,我只是习惯了这么写 //(function(){})();立即执行函 ...