HDU 3695 / POJ 3987 Computer Virus on Planet Pandora(AC自动机)(2010 Asia Fuzhou Regional Contest)
Description
Input
For each test case:
The first line is a integer n( 0 < n <= 250) indicating the number of virus pattern strings.
Then n lines follows, each represents a virus pattern string. Every pattern string stands for a virus. It’s guaranteed that those n pattern strings are all different so there are n different viruses. The length of pattern string is no more than 1,000 and a pattern string at least consists of one letter.
The last line of a test case is the program. The program may be described in a compressed format. A compressed program consists of capital letters and “compressors”. A “compressor” is in the following format:
[qx]
q is a number( 0 < q <= 5,000,000)and x is a capital letter. It means q consecutive letter xs in the original uncompressed program. For example, [6K] means ‘KKKKKK’ in the original program. So, if a compressed program is like:
AB[2D]E[7K]G
It actually is ABDDEKKKKKKKG after decompressed to original format. The length of the program is at least 1 and at most 5,100,000, no matter in the compressed format or after it is decompressed to original format.
Output
题目大意:给n个模式串,一个长串,问有多少个模式串出现在了长串中(翻转后的模式串也算)。
思路:多模式串匹配,裸的AC自动机题。对于一个模式串可能会是另一个模式串的子串的问题,只要每走一步之后把失配指针都走一下即可。不过据说都走一下会超时,所以要给每个点做一个标记,标记这个点的走过了,不用再走一次了。
PS:用指针的孩纸不回收内存会MLE,亲测……
PS2:题目好像没说一个串不能是另一个串的子串,但是我之前没考虑子串(只考虑了一个串是另一个串的后缀)依然AC了……
代码(HDU 1593MS/POJ 1671MS):
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std; const int MAXN = ;
const int MAX = ; struct Node {
Node *go[], *fail;
int src;
bool mark;
Node(int _src) {
src = _src;
fail = ; mark = ;
memset(go, , sizeof(go));
}
~Node() {
for(int i = ; i < ; ++i)
if(go[i]) delete go[i];
}
}; void build(Node *root, char *str, int id) {
Node *p = root;
for(int i = ; str[i]; ++i) {
int index = str[i] - 'A';
if(!p->go[index]) p->go[index] = new Node(-);
p = p->go[index];
}
p->src = id;
} void makeFail(Node *root) {
queue<Node*> que;que.push(root);
while(!que.empty()) {
Node *tmp = que.front(); que.pop();
for(int i = ; i < ; ++i) {
if(!tmp->go[i]) continue;
if(tmp == root) tmp->go[i]->fail = root;
else {
Node *p = tmp->fail;
while(p) {
if(p->go[i]) {
tmp->go[i]->fail = p->go[i];
break;
}
p = p->fail;
}
if(!p) tmp->go[i]->fail = root;
}
que.push(tmp->go[i]);
}
}
root->fail = root;
} bool vis[]; void solve(Node *root, char *str) {
Node *tmp = root;
for(char *now = str; *now; ++now) {
int index = *now - 'A';
while(tmp != root && !tmp->go[index]) tmp = tmp->fail;
if(tmp->go[index]) tmp = tmp->go[index];
Node *q = tmp;
while(q != root && !q->mark) {
q->mark = true;
if(q->src > ) vis[q->src] = true;
q = q->fail;
}
}
} int make_ans(int n) {
int ret = ;
for(int i = ; i <= n; ++i)
ret += vis[i];
return ret;
} void trans(char *ss, char *tt) {
for(int i = ; ss[i]; ++i) {
if(isalpha(ss[i])) *tt++ = ss[i];
else {
++i;
int t = ;
while(isdigit(ss[i])) t = t * + ss[i] - '', ++i;
for(int j = ; j < t; ++j) *tt++ = ss[i];
++i;
}
}
*tt = ;
} char ss[MAXN], s[MAXN];
char tmp[MAX]; int main() {
int T, n;
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
Node *root = new Node(-);
for(int i = ; i <= n; ++i) {
scanf("%s", tmp);
build(root, tmp, i);
reverse(tmp, tmp + strlen(tmp));
build(root, tmp, i);
}
makeFail(root);
scanf("%s", ss);
trans(ss, s);
//printf("%s\n", s);
memset(vis, , sizeof(vis));
solve(root, s);
printf("%d\n", make_ans(n));
delete root;
}
}
HDU 3695 / POJ 3987 Computer Virus on Planet Pandora(AC自动机)(2010 Asia Fuzhou Regional Contest)的更多相关文章
- HDU 3695 / POJ 3987 Computer Virus on Planet Pandora
Computer Virus on Planet Pandora Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 1353 ...
- POJ 3987 Computer Virus on Planet Pandora (AC自动机优化)
题意 问一个字符串中包含多少种模式串,该字符串的反向串包含也算. 思路 解析一下字符串,简单. 建自动机的时候,通过fail指针建立trie图.这样跑图的时候不再跳fail指针,相当于就是放弃了fai ...
- hdu ----3695 Computer Virus on Planet Pandora (ac自动机)
Computer Virus on Planet Pandora Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 256000/1280 ...
- HDU3695 - Computer Virus on Planet Pandora(AC自动机)
题目大意 给定一个文本串T,然后给定n个模式串,问有多少个模式串在文本串中出现,正反都可以 题解 建立好自动机后.把文本串T正反各匹配一次,刚开始一直TLE...后面找到原因是重复的子串很多以及有模式 ...
- HDU 3699 A hard Aoshu Problem(暴力枚举)(2010 Asia Fuzhou Regional Contest)
Description Math Olympiad is called “Aoshu” in China. Aoshu is very popular in elementary schools. N ...
- hdu 3695 Computer Virus on Planet Pandora(AC自己主动机)
题目连接:hdu 3695 Computer Virus on Planet Pandora 题目大意:给定一些病毒串,要求推断说给定串中包括几个病毒串,包括反转. 解题思路:将给定的字符串展开,然后 ...
- HDU 3698 Let the light guide us(DP+线段树)(2010 Asia Fuzhou Regional Contest)
Description Plain of despair was once an ancient battlefield where those brave spirits had rested in ...
- HDU 3697 Selecting courses(贪心+暴力)(2010 Asia Fuzhou Regional Contest)
Description A new Semester is coming and students are troubling for selecting courses. Students ...
- HDU 3696 Farm Game(拓扑+DP)(2010 Asia Fuzhou Regional Contest)
Description “Farm Game” is one of the most popular games in online community. In the community each ...
随机推荐
- C标准函数库(常用部分)
- safeNet
把那4个dll丢到C:\Windows\SysWOW64里去重启IIS,再测试
- linux init.d脚本编写模板
#!/bin/bash ### BEGIN INIT INFO # # Provides: location_server # Required-Start: $local_fs $remote_fs ...
- .NET平台上的Memcached客户端介绍
早上接到一个任务,需要对Linux服务器的Memcached的update操作进行性能测试,我发现我是一个典型的“手里拿着锤子, 就把所有问题都当成钉子”的人.我第一个念头就是,上Memcached的 ...
- JAVA命令大全
1.java.exe:======================运行java程序,这个相信每一位用Java的人知道了. 2.javac.exe:======================编译的Ja ...
- 【Derby 系列】Apache Derby 功能特点
前言 进入Derby 的应用开发之前,浏览一下derby的功能集,这样在真正选择的时候,可以决定Derby是不是适合你的应用. 本篇的是[Derby 系列]初级的第3篇. 1. Derby 是关系型数 ...
- LDA(Linear discriminate analysis)线性判别分析
LDA 线性判别分析与Fisher算法完全不同 LDA是基于最小错误贝叶斯决策规则的. 在EMG肌电信号分析中,... 未完待续:.....
- 微信和WeChat的合并月活跃账户达6.97亿
腾讯最新财报显示,微信和WeChat的合并月活跃账户于2015年底达6.97亿,同比增长39%.2016年初春节假期期间,通过微信支付收发的红包数量仅在6天内就超过320亿,同比增长9倍. 腾讯网络广 ...
- 交叉编译php5,、nginx、squid方法
本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 交叉编译php5 软件版本:php-5.4.27 依赖库:zlib,libxml2 交叉编译器:arm-hisi ...
- JavaScript 最佳实践
这个文档是基于JavaScript社区众多开发者的意见和经验,在开发JavaScript代码上的最佳实践和首选的方案的明细表.因为这是一个推荐的表而非原则性的方案,经验丰富的开发者可能对下面的表达会有 ...