Hdu 5384 Danganronpa (AC自动机模板)
2015-08-14 15:42
302 查看
题目链接:
Hdu 5384 Danganronpa
题目描述:
给出n个目标串Ai,m个模式串Bj,问每个目标串中m个模式串出现的次数总和为多少?
解题思路:
与Hdu 2222 Keywords Search十分相似,hdu2222求目标串中包含几个模式串,本题目求模式串在目标串中出现了几次(比赛的时候模板都不会就悲剧了┭┮﹏┭┮)
初学AC自动机可以参考大神博客,总结的真的炒鸡棒讷。涨姿势请点击下面尊贵的链接大人:
AC自动机算法总结 AC自动机模板
学完AC自动机就可以套模板解决这个站在冰柜上的高冷题目了~~~~.
对所有的Bj建立Trie图,然后在Trie的基础上建立fail数组,在fail数组上每遇到一个Bj的终点,都会对计算结果有1的贡献。
Hdu 5384 Danganronpa
题目描述:
给出n个目标串Ai,m个模式串Bj,问每个目标串中m个模式串出现的次数总和为多少?
解题思路:
与Hdu 2222 Keywords Search十分相似,hdu2222求目标串中包含几个模式串,本题目求模式串在目标串中出现了几次(比赛的时候模板都不会就悲剧了┭┮﹏┭┮)
初学AC自动机可以参考大神博客,总结的真的炒鸡棒讷。涨姿势请点击下面尊贵的链接大人:
AC自动机算法总结 AC自动机模板
学完AC自动机就可以套模板解决这个站在冰柜上的高冷题目了~~~~.
对所有的Bj建立Trie图,然后在Trie的基础上建立fail数组,在fail数组上每遇到一个Bj的终点,都会对计算结果有1的贡献。
#include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 100005; const int maxm = 10005; char A[maxn][maxm], B[maxm]; struct Trie { int next[maxn][26], fail[maxn], end[maxn]; int L, root; int newnode () { for (int i=0; i<26; i++) next[L][i] = -1; end[L] = 0; return L++; } void init () { L = 0; root = newnode(); } void insert (char s[]) { int now = root; for (int i=0; s[i]; i++) { if (next[now][s[i]-'a'] == -1) next[now][s[i]-'a'] = newnode(); now = next[now][s[i]-'a']; } end[now] ++; } void build () { queue <int> Q; fail[root] = root; for (int i=0; i<26; i++) if (next[root][i] == -1) next[root][i] = root; else { fail[next[root][i]] = root; Q.push(next[root][i]); } while (!Q.empty()) { int now = Q.front(); Q.pop (); for (int i=0; i<26; i++) { if (next[now][i] == -1) next[now][i] = next[fail[now]][i]; else { fail[next[now][i]] = next[fail[now]][i]; Q.push (next[now][i]); } } } } int query (char s[]) { int now = root, res = 0; for (int i=0; s[i]; i++) { now = next[now][s[i] - 'a']; int temp = now; while (temp != root) { res += end[temp]; temp = fail[temp]; } } return res; } }ac; int main () { int t, n, m; scanf ("%d", &t); while (t --) { ac.init (); scanf ("%d %d", &n, &m); for (int i=0; i<n; i++) scanf ("%s", A[i]); for (int i=0; i<m; i++) { scanf ("%s", B); ac.insert (B); } ac.build (); for (int i=0; i<n; i++) { int res = ac.query(A[i]); printf ("%d\n", res); } } return 0; }
相关文章推荐
- [转]Java transient关键字
- VC++ 用setsockopt()来控制recv()与send()的超时
- Yahoo!军规详解
- 对机器学习江湖的认识
- 如何做Sprint Planning-实例
- HDOJ--2094--产生冠军
- mybatis 实体属性和数据库字段不统一问题
- Android内存溢出处理方案
- 使用mybatis 实现批量插入,主键自增长
- Letter Combinations of a Phone Number
- centos6.3系统mysql数据库字符集设置,彻底解决乱码情况
- C# 数字转ASCII码
- poj 2236
- Selenium是什么
- [转] 为什么医疗咨询服务公司Evolent Health仅用4年就华丽上市?
- 二元多项式
- MYSQL 创建函数出错的解决方案
- rem px em
- epoll两种类型ET和LT区别(结合实际例子)
- 容斥原理