题目链接http://acm.hdu.edu.cn/showproblem.php?pid=2222

题目大意:多个模式串。问匹配串中含有多少个模式串。注意模式串有重复,所以要累计重复结果。

解题思路

AC自动机模板题。

一开始使用LRJ的坑爹静态模板,不支持重复的模式串。

在做AC自动机+DP的时候,扒了zcwwzdjn大神的动态优化(失配指向root)写法,以及借鉴了网上的AC自动机模板,

搞出了这么一个支持重复串的模板。

注意在计算last后缀链接的时候,都会修改last->cnt=0,是为了防止同一个模式串在匹配时候走了多遍。比如模:AA,匹:AAA,

修改last->cnt的结果是1,而不修改就是2。修改法在碰到HDU 2896这种需要计算多个匹配串的时候就萎了。

必须在修改之后,及时恢复。由于本身就使用了queue,所以修改时用queue记录一下哪些last被修改了,之后恢复一下就OK!

同时,修改法在HDU 3065中,统计一个模式串出现多少次也萎了。因为模式串必须要走多遍。

#include "cstdio"
#include "cstring"
#include "iostream"
#include "queue"
#include "string"
using namespace std;
struct Trie
{
Trie *next[],*fail;
int cnt;
}*root;
struct status
{
Trie *last;
int cnt;
status(Trie *last,int cnt):last(last),cnt(cnt) {}
};
Trie *newnode()
{
Trie *ret=new Trie;
memset(ret->next,,sizeof(ret->next));
ret->fail=;
ret->cnt=;
return ret;
}
void init() {root=newnode();}
void Insert(string str)
{
Trie *pos=root;
for(int i=;i<str.size();i++)
{
int c=str[i]-'a';
if(!pos->next[c]) pos->next[c]=newnode();
pos=pos->next[c];
}
pos->cnt++;
}
void getfail()
{
queue<Trie *> Q;
for(int c=;c<;c++)
{
if(root->next[c])
{
root->next[c]->fail=root;
Q.push(root->next[c]);
}
else root->next[c]=root;
}
while(!Q.empty())
{
Trie *x=Q.front();Q.pop();
for(int c=;c<;c++)
{
if(x->next[c])
{
x->next[c]->fail=x->fail->next[c];
Q.push(x->next[c]);
}
else x->next[c]=x->fail->next[c];
}
}
}
int find(string str)
{
Trie *pos=root,*last;
queue<status> Q;
int ans=;
for(int i=;i<str.size();i++)
{
int c=str[i]-'a';last;
if(pos->next[c])
{
pos=pos->next[c];
last=pos;
while(last->cnt)
{
Q.push(status(last,last->cnt));
ans+=last->cnt;
last->cnt=; //修改last->cnt
last=last->fail;
}
}
}
while(!Q.empty()) //恢复last->cnt
{
status x=Q.front();Q.pop();
x.last->cnt=x.cnt;
}
return ans;
}
int main()
{
//freopen("in.txt","r",stdin);
ios::sync_with_stdio(false);
int T,n;
string tt;
cin>>T;
while(T--)
{
cin>>n;
init();
for(int i=;i<=n;i++)
{
cin>>tt;
Insert(tt);
}
getfail();
cin>>tt;
int ans=find(tt);
printf("%d\n",ans);
}
}
11927003 2014-10-21 01:22:37 Accepted 2222 390MS 29480K 1942 B C++ Physcal

HDU 2222(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自动机模版题)

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

  5. HDU 2222 AC自动机 裸题

    题意: 问母串中出现多少个模式串 注意ac自动机的节点总数 #include <stdio.h> #include <string.h> #include <queue& ...

  6. HDU 2222 AC自动机模版题

    所学的AC自动机都源于斌哥和昀神的想法. 题意:求目标串中出现了几个模式串. 使用一个int型的end数组记录,查询一次. #include <cstdio> #include <c ...

  7. HDU 2222 & ac自动机模板

    题意: 求n个模板串在匹配串中出现了几个. SOL: 反正就是模板啦...似乎比KMP都简单----这么说似乎有点不道德...毕竟先看的KMP而他们并没有什么不同... 貌似自己的理解和他们画的图还是 ...

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

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

  9. Keywords Search HDU - 2222 AC自动机板子题

    In the modern time, Search engine came into the life of everybody like Google, Baidu, etc. Wiskey al ...

随机推荐

  1. samba服务搭建及管理

    关闭防火墙 # /etc/init.d/iptables stop # chkconfig --level iptables off 关闭SELINUX # vim /etc/sysconfig/se ...

  2. A desmos graph supersampling test

  3. linux文件分割(将大的日志文件分割成小的)

    linux文件分割(将大的日志文件分割成小的) linux下文件分割可以通过split命令来实现,可以指定按行数分割和安大小分割两种模式.Linux下文件合并可以通过cat命令来实现,非常简单. 在L ...

  4. CSS本页写样式

    <style type="text/css">p{ color:#ff0000; font-size:24px; font-family:"隶书"; ...

  5. 42.旋转数组的最小元素[Get min value of rotated array]

    [题目] 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个排好序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5 ...

  6. iOS 转载一篇利用dispatch_once创建单例的文章

    感谢文章原作者,http://bj007.blog.51cto.com/1701577/649413

  7. 利用FFmpeg生成视频缩略图 2.3.1

    1.下载FFmpeg文件包,解压包里的\bin\下的文件解压到 D:\ffmpeg\ 目录下. 下载地址 http://ffmpeg.zeranoe.com/builds/win32/static/ ...

  8. Java性能优化权威指南-读书笔记(二)-JVM性能调优-概述

    概述:JVM性能调优没有一个非常固定的设置,比如堆大小设置多少,老年代设置多少.而是要根据实际的应用程序的系统需求,实际的活跃内存等确定.正文: JVM调优工作流程 整个调优过程是不断重复的一个迭代, ...

  9. [火狐REST] 火狐REST 模拟 HTTP get, post请求

  10. Android之Activity框架

    在安卓应用中,经常需要Activity中经常需要有大量相似的Activity类,这些类往往有相似的结构与功能,因此产生了大量重复代码,为此,以下提供一种方法有效的降低了代码冗余. 定义Activity ...