Keywords Search HDU2222 AC自动机模板题
ac自动机说起来很复杂,其实和kmp是一样的思路,都是寻找相同前后缀,减少跳的次数。只要理解了kmp是怎么求next数组的,ac自动机bfs甚至比knp还好写。
这里大致说一下kmp求next数组的方法吧,假设现在要求第c个字符的next值(假设这个c很大,这样画图出来比较清晰方便理解),因为遍历过程中我们已经知道了第c-1个字符的next为x(假设比c小很多),即next[c-1] = x。那就代表我们知道了a[1]—a[x]这一段和a[c-1-x]—a[c-1]这一段是相等的对吧。
那么现在有两种情况
一。a[x+1] 和 a[c]相等,那么显然变成了a[1]—a[x+1] 这一段和a[c-1-x]—a[c]这一段相等,即c位置的相同前后缀长度比c-1多了1,就是next[c-1]+1;
即原来是:
1——————————x == c-1-x ————————————————c-1 ① 由于a[x+1] == a[c],变成了
1——————————x+1 == c-1-x——————————————————c
二。如果不相等,那么我们在1——x这一段下功夫,假设next[x] = y,即1——y == x-y——x这两段相等,注意根据①式,x-y——x == c-1-y——c-1,画个图就很清楚了,所以如果a[y+1] == a[c],那么相同前后缀长度就是y+1了。
即因为
1——————————x == c-1-x————————————————c-1
1——y == x-y———x == c-1-x——c-1-x+y == c-1-y————c-1 由于a[y+1] == a[c],变成了
1——y+1 == c-1-y——————c
那如果a[y+1] 与a[c]还是不相等怎么办?其实细心的话应该发现这是一个递归过程了——只要再找next[y],循环上面的过程就可以了,想明白这个过程再去看求next数组的代码就很容易理解了。
最后还是上这道题代码:
#include <iostream>
#include <string.h>
#include <cstdio>
#include <queue>
#include <set>
#include <stack>
#include <math.h>
#include <string>
#include <algorithm> #define SIGMA_SIZE 26
#define pii pair<int,int>
#define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) (x&-x)
#define fode(i, a, b) for(int i=a; i>=b; i--)
#define foe(i, a, b) for(int i=a; i<=b; i++)
#define fod(i, a, b) for(int i=a; i>b; i--)
#define fo(i, a, b) for(int i=a; i<b; i++)
//#pragma warning ( disable : 4996 ) using namespace std;
typedef long long LL;
inline LL LMax(LL a, LL b) { return a>b ? a : b; }
inline LL LMin(LL a, LL b) { return a>b ? b : a; }
inline LL lgcd(LL a, LL b) { return b == ? a : lgcd(b, a%b); }
inline LL llcm(LL a, LL b) { return a / lgcd(a, b)*b; } //a*b = gcd*lcm
inline int Max(int a, int b) { return a>b ? a : b; }
inline int Min(int a, int b) { return a>b ? b : a; }
inline int gcd(int a, int b) { return b == ? a : gcd(b, a%b); }
inline int lcm(int a, int b) { return a / gcd(a, b)*b; } //a*b = gcd*lcm
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL lmod = 1e9+;
const int mod = ;
const double eps = 1e-;
const int inf = 0x3f3f3f3f;
const int maxk = 1e5+;
const int maxm = *;
const int maxn = 5e5+; struct node {
node *fail, *s[];
int w;
node() {} void init() {
fail = NULL;
fo(i, , ) s[i] = NULL;
w = ;
}
}*head; int n, ans;
char str[];
queue<node*> q; node* getfail(node* p, int x)
{
if (p->s[x] != NULL) return p->s[x];
else {
if (p == head) return head;
else return getfail(p->fail, x);
}
} void build()
{
node* root = head;
node* tmp; int len = strlen(str);
for ( int j = ; j < len; j++ )
{
int k = str[j]-'a';
if (root->s[k] == NULL) {
tmp = new node; tmp->init();
tmp->fail = head;
root->s[k] = tmp;
} root = root->s[k];
//标记单词结尾
if (j == len-) root->w++;
}
} void build_ac()
{
node* r;
while(!q.empty()) q.pop();
q.push(head);
while(!q.empty())
{
r = q.front(); q.pop();
fo(j, , )
{
if (r->s[j] != NULL) {
q.push(r->s[j]);
if (r == head) r->s[j]->fail = head;
else r->s[j]->fail = getfail(r->fail, j);
}
}
}
return;
} void solve()
{
int len = strlen(str);
node *tmp, *r = head;
fo(j, , len)
{
int k = str[j]-'a';
//找到前缀
while( r->s[k]==NULL && r != head ) r = r->fail;
//自动机向下匹配
//如果可以匹配,则进入下一节点,否则返回头节点
r = (r->s[k]==NULL) ? head : r->s[k];
tmp = r; //如果单词a出现,则他的前缀也全部出现过
while(tmp != head) {
ans += tmp->w;
tmp->w = ;
tmp = tmp->fail;
}
}
return;
} void init()
{
cin >> n; ans = ;
head = new node, head->init();
foe(i, , n)
scanf("%s", str), build(); build_ac();
scanf("%s", str);
} int main()
{ #ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif int t; cin >> t;
while(t--)
{
init();
solve();
printf("%d\n", ans);
} return ;
}
Keywords Search HDU2222 AC自动机模板题的更多相关文章
- HDU-2222 Keywords Search(AC自动机--模板题)
题目大意:统计一共出现了多少次模板串. 题目分析:AC自动机的模板题.不过这题有坑,相同的模板串不能只算一次. 代码如下: # include<iostream> # include< ...
- HDU 2222 Keywords Search(AC自动机模板题)
http://acm.hdu.edu.cn/showproblem.php?pid=2222 题意:给出多个单词,最后再给出一个模式串,求在该模式串中包含了多少个单词. 思路: AC自动机的模板题. ...
- hdu_2222: Keywords Search(AC自动机模板题)
题目链接 统计一段字符串中有多少个模板串在里面出现过 #include<bits/stdc++.h> using namespace std; ; struct Trie { ]; int ...
- HDU2222 Keywords Search(AC自动机模板)
AC自动机是一种多模式匹配的算法.大概过程如下: 首先所有模式串构造一棵Trie树,Trie树上的每个非根结点都代表一个从根出发到该点路径的字符串. 然后每个结点都计算出其fail指针的值,这个fai ...
- HDU 2222 Keywords Search(AC自动机模版题)
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- HDU 2222 Keywords Search 【AC自动机模板】
询问有多少个模式串出现在了文本串里面.将模式串插入Trie树中,然后跑一边AC自动机统计一下就哦了. 献上一份模板. #include <cstdio> #include <cstr ...
- HDU 2222:Keywords Search(AC自动机模板)
http://acm.hdu.edu.cn/showproblem.php?pid=2222 KMP是单模式串匹配的算法,而AC自动机是用于多模式串匹配的算法.主要由Trie和KMP的思想构成. 题意 ...
- HDU 2222 AC自动机模板题
题目: http://acm.hdu.edu.cn/showproblem.php?pid=2222 AC自动机模板题 我现在对AC自动机的理解还一般,就贴一下我参考学习的两篇博客的链接: http: ...
- HDU 3065 (AC自动机模板题)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3065 题目大意:多个模式串,范围是大写字母.匹配串的字符范围是(0~127).问匹配串中含有哪几种模 ...
随机推荐
- hdu多校第一场1004(hdu6581)Vacation 签到
题意:有n+1辆车,每辆车都有一定的长度,速度和距离终点的距离,第1-n辆车在前面依次排列,第0辆车在最后面.不允许超车,一旦后车追上前车,后车就减速,求第0辆车最快什么时候能到达终点? 思路:对于每 ...
- Mybatis笔记 – Po映射类型
一.输入映射类型 parameterType定义输入到sql中的映射类型,可以是 简单类型 .po类对象(可自动生成 或 手动定义). pojo包装对象(用于综合查询,UserCustom用户自定 ...
- Metasploit 模块和位置
Metasploit Framework由许多的模块组成的. 一.Exploits(漏洞模块) 定义为使用“有效载荷(payloads)”的模块 没有“有效载荷”的攻击是辅助模块 二.Payloads ...
- JSON Web Token (JWT)生成Token及解密实战。
昨天讲解了JWT的介绍.应用场景.优点及注意事项等,今天来个JWT具体的使用实践吧. 从JWT官网支持的类库来看,jjwt是Java支持的算法中最全的,推荐使用,网址如下. https://githu ...
- IntelliJ IDEA无法创建springboot项目解决办法
最佳解决办法:IntelliJ IDEA---右键---以管理员身份运行. 方法二: 1.打开控制面板--系统和安全--windows防火墙 2.找到自己的默认浏览器,打勾,这里是谷歌浏览器 3.打开 ...
- 错误Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/hadoop/fs/FSDataInputStream排查思路
spark1(默认CDH自带版本)不存在这个问题,主要是升级了spark2(CDHparcel升级)版本安装后需要依赖到spark1的旧配置去读取hadoop集群的依赖包. 1./etc/spark2 ...
- redhat7和redhat6混合搭建文档
1.下载cm对应redhat7的版本.2.修改/opt/cloudera/cm-5.10.0/etc/cloudera-scm-agent/config.ini成为中心机器hostname/ip(ma ...
- ubuntu安装更新命令
ubuntu16.04LTS 进入ubuntu系统后,打开一个终端,如图所示.此时以普通用户身份登录. 由于更新系统需要用到管理员权限,因此要么使用"su -"直接切换到roo ...
- soj114 中位数
题意:给你一个长度为2n-1的数组A,设Bi是A的1~2i-1的中位数.问打乱A,有多少种不同的B序列? 标程: #include<bits/stdc++.h> using namespa ...
- Java 基础 - Object.clone()深拷贝和浅拷贝
作者:YSOcean 出处:http://www.cnblogs.com/ysocean/ 本文版权归作者所有,欢迎转载,但未经作者同意不能转载,否则保留追究法律责任的权利. ---------- ...