题目大意:输入几个子串,然后输入一个母串,问在母串里面包含几个子串。
 
分析:刚学习的AC自动机,据说这是个最基础的模板题,所以也是用了最基本的写法来完成的,当然也借鉴了别人的代码思想,确实是个很神奇的东西,如果不懂KMP的话,最好先学学KMP再来学这个,会理解的更深刻一些。
 
代码如下:
=======================================================================================================================
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std; const int MAXN = 1e6+;
const int MAXM = ;
const int oo = 1e9+; char MumStr[MAXN];///母串 struct Ac_Trie_Node
{///Fail 失败节点
Ac_Trie_Node *Fail, *next[MAXM];
int leaf;///已这个节点为叶子节点的数目
}; void Insert(Ac_Trie_Node *root, char s[])
{///插入所有的模式串
Ac_Trie_Node *p = root; for(int i=; s[i]; i++)
{
int k = s[i]-'a'; if(p->next[k] == NULL)
p->next[k] = new Ac_Trie_Node();
p = p->next[k];
} p->leaf += ;
}
void GetFail(Ac_Trie_Node *root)
{///构造失败指针
queue<Ac_Trie_Node *> Q;
Ac_Trie_Node *p = root, *temp; for(int i=; i<MAXM; i++)
{
if(p->next[i] != NULL)
{
p->next[i]->Fail = root;
Q.push(p->next[i]);
}
} while(Q.size())
{
p = Q.front();Q.pop(); for(int i=; i<MAXM; i++) if(p->next[i])
{///如果节点p的next[i]不为空 temp = p->Fail;///查找另一个最近的next[i]不为空的地方 while(temp != NULL)
{
if(temp->next[i] != NULL)
{///查找到
p->next[i]->Fail = temp->next[i];
break;
} temp = temp->Fail;
} if(temp == NULL)
p->next[i]->Fail = root; Q.push(p->next[i]);
}
}
}
void FreeTrie(Ac_Trie_Node *root)
{///释放内存
Ac_Trie_Node *p = root; for(int i=; i<MAXM; i++)
{
if(p->next[i] != NULL)
FreeTrie(p->next[i]);
} free(p);
}
int Query(Ac_Trie_Node *root)
{
Ac_Trie_Node *p = root, *temp;
int sum=; for(int i=; MumStr[i]; i++)
{
int k = MumStr[i]-'a'; while(!p->next[k] && p != root)
p = p->Fail; if(!p->next[k])continue;///根节点下面没有这个字母 temp = p = p->next[k]; while(temp != root && temp->leaf != -)
{///查找路径上的所有子节串,因为每个子串只出现一次,所以赋值为-1,防止重搜
sum += temp->leaf;
temp->leaf = -;
temp = temp->Fail;
}
} return sum;
} int main()
{
int T; scanf("%d", &T); while(T--)
{
int M; char s[];
Ac_Trie_Node *root = new Ac_Trie_Node(); scanf("%d", &M); while(M--)
{
scanf("%s", s);
Insert(root, s);
} GetFail(root); scanf("%s", MumStr);
int ans = Query(root); printf("%d\n", ans); FreeTrie(root);
} return ;
}

Keywords Search - HDU 2222(AC自动机模板)的更多相关文章

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

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

  2. HDU 2222 AC自动机模板题

    题目: http://acm.hdu.edu.cn/showproblem.php?pid=2222 AC自动机模板题 我现在对AC自动机的理解还一般,就贴一下我参考学习的两篇博客的链接: http: ...

  3. HDU 2222 & ac自动机模板

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

  4. AC日记——Keywords Search hdu 2222

    2222 思路: ac自动机模板题: 代码: #include <cstdio> #include <cstring> #include <iostream> #i ...

  5. HDU 3065 (AC自动机模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3065 题目大意:多个模式串,范围是大写字母.匹配串的字符范围是(0~127).问匹配串中含有哪几种模 ...

  6. HDU 2896 (AC自动机模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2896 题目大意:多个模式串.多个匹配串.其中串的字符范围是(0~127).问匹配串中含有哪几个模式串 ...

  7. Keywords Search HDU - 2222 ( ac自动机)模版题

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

  8. Keywords Search HDU - 2222(ac自动机板题。。)

    求一个字符串上有多少个匹配的单词 看着卿学姐的板子写的 指针形式: #include <iostream> #include <cstdio> #include <sst ...

  9. HDU 2222 (AC自动机)

    HDU 2222 Keywords search Problem : 给若干个模式串,询问目标串中出现了多少个模式串. Solution : 复习了一下AC自动机.需要注意AC自动机中的fail,和n ...

随机推荐

  1. window.showModalDialog()复制内容

    ShowModalDialog 打开的 页面上加入个 <span id="mySpan" name="mySpan" contentEditable=&q ...

  2. .NET中的三种Timer的区别和用法(转)

      最近正好做一个WEB中定期执行的程序,而.NET中有3个不同的定时器.所以正好研究研究.这3个定时器分别是: //1.实现按用户定义的时间间隔引发事件的计时器.此计时器最宜用于 Windows 窗 ...

  3. C# 枚举

    一.在学习枚举之前,首先来听听枚举的优点. 1.枚举能够使代码更加清晰,它允许使用描述性的名称表示整数值. 2.枚举使代码更易于维护,有助于确保给变量指定合法的.期望的值. 3.枚举使代码更易输入. ...

  4. 将日期和时间作为 struct tm型的值直接向二进制文件进行读写

    #include <stdio.h> #include <time.h> char data_file[]="D:\\%\\datetime.dat"; v ...

  5. sicily-2499 平方数

    题目分析: 一个数可以表示成四种状态,所以可以用一个状态数组来存放该数由几个数的平方和表示.1.表示该数本身是完全平方.2.表示该数是由两个平方和3.表示三个.4.表示4个.一次遍历找出本身是完全平方 ...

  6. SGU 117.Counting

    时间限制: 0.25 sec. 空间限制: 4096 KB 题目大意: 给你n,m,k(都小于10001),和 n 个数,求这n个数中有多少个数的m次幂能够整除k.(即 n i^m % k==0). ...

  7. wordpress整站搬家总结

    去年图便宜,也没准备认真写博文,所以花了几百元钱买了个国内空间(域名已经备案).购买了以后,放了一个wordpress博客,没事的时候写写博文,但从没有抽出时间去写,文章的质量也不追求.一开始还可以, ...

  8. 关于call 与 apply 那些事

    1.定义: call : 调用一个对象的一个方法,以另一个对象替换当前的对象. apply : 应用某一对象的一个方法,用另一个对象替换当前的对象. 2.用法: call:call(thisObj, ...

  9. yii2源码学习笔记(六)

    Behvaior类,Behavior类是所有事件类的基类: 目录yii2\base\Behavior.php <?php /** * @link http://www.yiiframework. ...

  10. TatukGIS-TGIS_LayerVector-LocateEx

    方法原型: function LocateEx(const _ptg: TGIS_Point; const _prec: Double; const _uid: Integer; var _dist: ...