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

题目大意:有多个文本,多个模式串。问每个模式串中,有多少个文本?(匹配可重复)

解题思路

传统AC自动机是计算单个文本中,模式串出现次数。

这里比较特殊,每个文本需要单独计算,而且每个匹配在每个文本中只能计数1次。

比如add,d只能计数1次,而不是;两次。

所以循环逐个对文本Find。每个Find里,进行Hash,保证每个匹配串只计数1次。

由于匹配串可重复,在Insert之前,也需要离散化Hash一下,把重复的下标,指向最先插入的下标。

另外,本题会卡掉不正确AC自动机模板( Find里要写成While(last!=root)而不是While(last->cnt)  )

代码

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include "cstdio"
#include "cstring"
#include "string"
#include "iostream"
#include "queue"
#include "vector"
#include "algorithm"
#include "map"
using namespace std;
#define maxn 26
int ans[],mt[];
string P[];
struct Trie
{
Trie *next[maxn],*fail;
int cnt;
}*root;
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,int index)
{
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=index;
}
void getfail()
{
queue<Trie *> Q;
for(int c=;c<maxn;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<maxn;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];
}
}
}
void Find(string str)
{
map<int,int> Hash;
Trie *pos=root,*last;
for(int i=;i<str.size();i++)
{
int c=str[i]-'a';last;
if(c<||c>maxn) {pos=root;continue;}
if(pos->next[c])
{
pos=pos->next[c];
last=pos;
while(last!=root)
{
if(!Hash.count(last->cnt))
{
ans[last->cnt]++;
Hash[last->cnt]++;
}
last=last->fail;
}
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
ios::sync_with_stdio(false);
int n,m,s;
string tmp;
while(cin>>n)
{
map<string,int> ms;
memset(ans,,sizeof(ans));
memset(mt,,sizeof(mt));
init();
for(int i=;i<=n;i++) cin>>P[i];
cin>>s;
for(int i=;i<=s;i++)
{
cin>>tmp;
if(!ms.count(tmp))
{
Insert(tmp,i);
ms[tmp]=i;
mt[i]=i;
}
else mt[i]=ms[tmp];
}
getfail();
for(int i=;i<=n;i++) Find(P[i]);
for(int i=;i<=s;i++) cout<<ans[mt[i]]<<endl;
}
}

HDU 2846 (AC自动机+多文本匹配)的更多相关文章

  1. hdu 2896 AC自动机

    // hdu 2896 AC自动机 // // 题目大意: // // 给你n个短串,然后给你q串长字符串,要求每个长字符串中 // 是否出现短串,出现的短串各是什么 // // 解题思路: // / ...

  2. hdu 3065 AC自动机

    // hdu 3065 AC自动机 // // 题目大意: // // 给你n个短串,然后给你一个长串,问:各个短串在长串中,出现了多少次 // // 解题思路: // // AC自动机,插入,构建, ...

  3. hdu 5880 AC自动机

    Family View Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  4. hdu 2296 aC自动机+dp(得到价值最大的字符串)

    Ring Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  5. hdu 2825 aC自动机+状压dp

    Wireless Password Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  6. hdu 3065 AC自动机(各子串出现的次数)

    病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  7. HDU - 2222,HDU - 2896,HDU - 3065,ZOJ - 3430 AC自动机求文本串和模式串信息(模板题)

    最近正在学AC自动机,按照惯例需要刷一套kuangbin的AC自动机专题巩固 在网上看过很多模板,感觉kuangbin大神的模板最为简洁,于是就选择了用kuangbin大神的模板. AC自动机其实就是 ...

  8. HDU:2222-Keywords Search(AC自动机模板,匹配模拟)

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

  9. HDU 5384 AC自动机

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=5384 题意:给n个母串,给m个匹配串,求每个母串依次和匹配串匹配,能得到的数目和. 分析:之前并不知道AC ...

随机推荐

  1. 四、优化及调试--网站优化--SEO在网页制作中的应用

    SEO分类:白帽SEO.黑帽SEO 白帽SEO: 内容上的SEO: 网站标题.关键字.描述 网站内容优化 Robot.txt文件 网站地图 增加外链引用 前端SEO: 网站结构布局优化 扁平化结构(一 ...

  2. centos vsftp 服务器配置

    安装服务端: # yum install -y vsftpd 安装客服端: # yum install ftp -y http://os.51cto.com/art/201408/448630.htm

  3. [LeetCode] Add Two Numbers

    You are given two linked lists representing two non-negative numbers. The digits are stored in rever ...

  4. [LeetCode] Remove Element (三种解法)

    Given an array and a value, remove all instances of that value in place and return the new length. T ...

  5. Linux 端口-> PID -> 启动目录

    1.    lsof -i :8443   找到PID 比如说是5413 2.    ps aux | grep 5413  可以得到一些信息 3.    除了第二步的方式,更直观的是 cd /pro ...

  6. VS2013 当前不会命中断点,还没有为该文档加载任何符号

    方法一: 把ie的 调试 打开,然后调试的时候 会问你 是在新示例中打开 还是 当前示例,你选择当前的就行了.还有 建议你用 ie8.0的 开发者工具 调试  非常舒服 我已经 早就不用debuger ...

  7. jquery 仿百度搜索下拉框的插件

    转载地址:http://www.open-open.com/lib/view/open1420624048437.html 今天写了个下拉插件分享出来 效果: , 可以搜素,也可以使用上下键选择匹配出 ...

  8. loj 1210 (求最少的加边数使得图变成强连通)

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1210 思路:首先是缩点染色,然后重建并且统计新图中的每个点的入度和出度,于是答案就是m ...

  9. javascript中时间的手动创建date的方式

    new Date("month dd,yyyy hh:mm:ss"); new Date("month dd,yyyy"); new Date(yyyy,mth ...

  10. 网上下载的CHM帮助文件打不开的解决办法。

    我的机器 装的是 Windows server 2008 操作系统.他的安全性比较高. 我在网上下载了一个 CHM 帮助文档.结果打不开. 现象: 打开时 ,提示 安全警告, 提示:来自Interne ...