题目传送门

  快速的通道I

  快速的通道II

题目大意

  给定一堆短串,和一个文本串,问哪些短串在文本串中出现的次数最多。

  我觉得刘汝佳的做法,时间复杂度有问题。只是似乎这道题短串串长太短不好卡。比如给出的串是一坨$a$。暴力跳$last$会比较gg。

  考虑如何计算一个短串在长串中的出现次数。

  当短串在长串的某个位置出现的时候,这意味着它的结束位置在fail树上的祖先中某个状态是短串的终止状态。

  我们会在长串经过的每个状态都去做这样一个操作来统计每个短串出现的次数。

  这个可以看成在fail树上的以根为端点的链上修改操作。

  由于询问可以看成是离线的,所以每次可以单点修改cnt,最后做一次前缀和。

Code

 /**
* UVa Live
* Problem#4670
* Accepted
* Time: 45ms
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
typedef bool boolean; const int MaxNode = , N = , L = ; typedef class TrieNode {
public:
int cnt;
TrieNode* ch[];
TrieNode* fail;
}TrieNode; TrieNode pool[MaxNode];
TrieNode *top; TrieNode* newnode() {
top->cnt = ;
memset(top->ch, , sizeof(top->ch));
top->fail = NULL;
return top++;
} typedef class AhoCorasick {
public:
TrieNode* rt; AhoCorasick() {
top = pool;
rt = newnode();
} TrieNode* insert(char* str) {
TrieNode* p = rt;
for (int i = , c; str[i]; i++) {
c = str[i] - 'a';
if (!p->ch[c])
p->ch[c] = newnode();
p = p->ch[c];
}
return p;
} void build() {
queue<TrieNode*> que;
rt->fail = NULL;
que.push(rt);
while (!que.empty()) {
TrieNode* p = que.front();
que.pop();
for (int i = ; i < ; i++) {
TrieNode *np = p->ch[i];
if (!np) continue;
que.push(np);
TrieNode* f = p->fail;
while (f && !f->ch[i]) f = f->fail;
if (!f)
np->fail = rt;
else
np->fail = f->ch[i];
}
}
} void query(char *str) {
TrieNode *p = rt;
for (int i = ; str[i]; i++) {
int c = str[i] - 'a';
while (p && !p->ch[c]) p = p->fail;
if (!p)
p = rt;
else
p = p->ch[c];
p->cnt++;
}
for (p = top - ; p != pool; p--)
p->fail->cnt += p->cnt;
}
}AhoCorasick; int n;
AhoCorasick ac;
char S[];
char T[N][L];
TrieNode* ps[N]; inline boolean init() {
scanf("%d", &n);
if (!n) return false;
ac = AhoCorasick();
for (int i = ; i <= n; i++) {
scanf("%s", T[i]);
ps[i] = ac.insert(T[i]);
}
scanf("%s", S);
return true;
} inline void solve() {
ac.build();
ac.query(S);
int maxt = ;
for (int i = ; i <= n; i++)
if (ps[i]->cnt > maxt)
maxt = ps[i]->cnt;
printf("%d\n", maxt);
for (int i = ; i <= n; i++)
if (ps[i]->cnt == maxt)
puts(T[i]);
} int main() {
while(init())
solve();
return ;
}

UVa Live 4670 Dominating Patterns - Aho-Corasick自动机的更多相关文章

  1. LA 4670 Dominating Patterns (AC自动机)

    题意:给定n个字符串和一个文本串,查找哪个字符串出现的次数的最多. 析:一匹配多,很明显是AC自动机.只需要对原来的进行修改一下,就可以得到这个题的答案, 计算过程中,要更新次数,并且要映射字符串.如 ...

  2. UVALive 4670 Dominating Patterns (AC自动机)

    AC自动机的裸题.学了kmp和Trie以后不难看懂. 有一些变化,比如0的定义和f的指向,和建立失配边,以及多了后缀连接数组last.没有试过把失配边直接当成普通边(一开始还是先这样写吧). #inc ...

  3. 【暑假】[实用数据结构]UVAlive 4670 Dominating Patterns

    UVAlive 4670 Dominating Patterns 题目:   Dominating Patterns   Time Limit: 3000MS   Memory Limit: Unkn ...

  4. LA 4670 Dominating Patterns (AC自动机)

    题意:给定一个一篇文章,然后下面有一些单词,问这些单词在这文章中出现过几次. 析:这是一个AC自动机的裸板,最后在匹配完之后再统计数目就好. 代码如下: #pragma comment(linker, ...

  5. UVALive 4670 Dominating Patterns --AC自动机第一题

    题意:多个模板串,一个文本串,求出那些模板串在文本串中出现次数最多. 解法:AC自动机入门模板题. 代码: #include <iostream> #include <cstdio& ...

  6. AC自动机 LA 4670 Dominating Patterns

    题目传送门 题意:训练指南P216 分析:求出现最多次数的字串,那么对每个字串映射id,cnt记录次数求最大就可以了. #include <bits/stdc++.h> using nam ...

  7. UVALive - 4670 Dominating Patterns AC 自动机

    input n 1<=n<=150 word1 word2 ... wordn 1<=len(wirdi)<=70 s 1<=len(s)<=1000000 out ...

  8. UVALive-4670 Dominating Patterns(AC自动机)

    题目大意:找出出现次数最多的模式串. 题目分析:AC自动机裸题. 代码如下: # include<iostream> # include<cstdio> # include&l ...

  9. uvalive 4670 Dominating Patterns

    在文本串中找出现次数最多的子串. 思路:AC自动机模板+修改一下print函数. #include<stdio.h> #include<math.h> #include< ...

随机推荐

  1. cocos2d CCNode类(节点属性大全)

    1 CCNode是cocos2d-x中一个很重要的类,CCNode是场景.层.菜单.精灵等的父类.而我们在使用cocos2d-x时,接触最多的就是场景.层.菜单.精灵等.所以有必要先弄懂CCNode类 ...

  2. VB脚本错误,系统找不到制定的文件 。代码:80070002

    希望得到网友的答案:非常感谢!

  3. 并发工具CyclicBarrier

    想想一下这样一个场景,有多个人需要过河,河上有一条船,船要等待满10个人才过河,过完河后每个人又各自行动. 这里的人相当于线程,注意这里,每个线程运行到一半的时候,它就要等待一个条件,即船满过河的条件 ...

  4. sublime text3 增加代码片段(snipper)

    有时候编写代码时有些代码片段经常会用到,如果能将这些代码片段整理,再在需要的时候通过某些条件触发,那无疑是非常方便的! 创建方法:工具->插件开发->新建代码片段 默认产生的内容是: &l ...

  5. Keras 处理 不平衡的数据的分类问题 imbalance data 或者 highly skewed data

    处理不平衡的数据集的时候,可以使用对数据加权来提高数量较小类的被选中的概率,具体方式如下 fit(self, x, y, batch_size=32, nb_epoch=10, verbose=1, ...

  6. linux 安装 Python

    一. 打开终端,输入:wget https://www.python.org/ftp/python/3.5.0/Python-3.5.0b4.tgz 下载完毕后 输入解压命令:tar –zxvf Py ...

  7. DSO安装试运行

    参考DSO初探 其中Pangolin安装的时候could not find GLEW,参考这里 libx11-dev libxmu-dev libglu1-mesa-dev libgl2ps-dev ...

  8. npm 代理的设置和取消

    管理员权限下的控制台输入: 设置代理 npm config set proxy=http://127.0.0.1:8080 npm config set registry=http://registr ...

  9. FileChannel

    1, FileChannel 虚拟类,不可以直接实例化,可以通过FileInputStream  FileOutputStream 获取 例:文件的复制 public class ChannelDem ...

  10. 设计模式之Composite(组合)(转)

    Composite定义: 将对象以树形结构组织起来,以达成"部分-整体" 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性. Composite比较容易理解,想到Comp ...