题目链接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. mac安装最新版本的git

    文章转载自我的个人博客 http://www.iwangzheng.com/ 1.下载一个安装包哦 在mac下安装git,首先下载一个git安装包,这里我选的是git-1.9.3.tar , 因为这是 ...

  2. nginx: [emerg] getpwnam(“www”) failed

    在配置nginx 时提示如下错误时:nginx: [emerg] getpwnam(“www”) failed 解决方案一 在nginx.conf中 把user nobody的注释去掉既可 解决方案二 ...

  3. STL库函数 持续更新

    *容器 (1)顺序容器 vector[顺序表直接访问] depue[前后直接访问] list[双向链表] vector 检索(用operator[ ])速度快 .push_back 在数组的最后添加一 ...

  4. Linux netstat +awk 看攻击IP

     netstat -n | awk '/^tcp/ {n=split($(NF-1),array,":");if(n<=2)++S[array[(1)]];else++S[a ...

  5. php自定义函数call_user_func和call_user_func_array详解

    看UCenter的时候有一个函数call_user_func,百思不得其解,因为我以为是自己定义的函数,结果到处都找不到,后来百度了一下才知道call_user_func是内置函 call_user_ ...

  6. 【Linux】为啥查某个进程的线程,查出来的所有线程的pid不一样啊

    楼上说的linux线程和进程是一样的,这个说法是错误的. 看了楼主的问题,感觉楼主是被PID给弄混了,线程进程都会有自己的ID,这个ID就叫做PID,PID是不特指进程ID,线程ID也可以叫做PID. ...

  7. HTML表单元素Emil和密码

    <form action="" method="post" name="myform"><p>E-mail:< ...

  8. python模拟浏览器保存Cookie进行会话

    #! /usr/bin/env python # -*-coding:utf- -*- import urllib import urllib2 import cookielib class NetR ...

  9. DP:Space Elevator(POJ 2392)

    太空电梯 题目大意:一群牛想造电梯到太空,电梯都是由一个一个块组成的,每一种块不能超过这个类型的高度,且每一种块都有各自的高度,有固定数量,问最高能造多高. 这题就是1742的翻版,对ai排个序就可以 ...

  10. ytu 2002:C语言实验——单词统计(水题)

    C语言实验——单词统计 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 61  Solved: 34[Submit][Status][Web Board] ...