hdu 3065病毒侵袭持续中(ac自动机)

题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=3065

中文题题意不解释了。

依旧稍微改一下ac自动机模版就能过了。还有一个坑点!是多组数据!!!

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
const int M = 5e4 + 10 , MM = 2e6 + 10 , N = 1e3 + 10;
char str[N][60] , sl[MM];
int Next[M][27] , fail[M] , End[M] , c[M / 10] , L , root , cnt , ans;
int newnode() {
    for(int i = 0 ; i <= 26 ; i++) {
        Next[L][i] = -1;
    }
    End[L++] = 0;
    return L - 1;
}
void init() {
    L = 0 , ans = 0;
    root = newnode();
    memset(c , 0 , sizeof(c));
}
void build(char s[]) {
    int len = strlen(s);
    int now = root;
    for(int i = 0 ; i < len ; i++) {
        int id = s[i] - ‘A‘;
        if(Next[now][id] == -1) {
            Next[now][id] = newnode();
        }
        now = Next[now][id];
    }
    End[now] = ++ans;
}
void get_fail() {
    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]);
            }
        }
    }
}
void match(char s[]) {
    int len = strlen(s);
    int now = root;
    for(int i = 0 ; i < len ; i++) {
        int id;
        if(s[i] <= ‘Z‘ && s[i] >= ‘A‘) {
            id = s[i] - ‘A‘;
        }
        else {
            id = 26;
        }
        now = Next[now][id];
        int tmp = now;
        while(tmp != root) {
            if(End[tmp] > 0) {
                c[End[tmp]]++;
            }
            tmp = fail[tmp];
        }
    }
}
int main()
{
    int n;
    while(scanf("%d" , &n) != EOF) {
        init();
        for(int i = 0 ; i < n ; i++) {
            scanf("%s" , str[i + 1]);
            build(str[i + 1]);
        }
        getchar();
        get_fail();
        gets(sl);
        match(sl);
        for(int i = 0 ; i < n ; i++) {
            if(c[i + 1] != 0) {
                printf("%s: %d\n" , str[i + 1] , c[i + 1]);
            }
        }
    }
    return 0;
}
时间: 2024-10-17 18:45:52

hdu 3065病毒侵袭持续中(ac自动机)的相关文章

HDU 3065 病毒侵袭持续中 AC自动机题解

其实本题比HDU的病毒侵袭1还简单,不过有一个陷阱卡到我了:就是搜索text的时候,当遇到的字母不是大写字母的时候,那么就要重新从根节点开始搜索,否则就会答案错误. 那么一点陷阱,居然没想到啊. 教训啊:看来对不太平常的地方,需要更加深入的思考,才能发现其中的陷阱,否则就WA了. #include <stdio.h> #include <string.h> #include <queue> using std::queue; const int MAX_N = 1001

HDU 3065 病毒侵袭持续中(AC自动机)

病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 15137    Accepted Submission(s): 5161 Problem Description 小t非常感谢大家帮忙解决了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的"万恶之源".这是一个庞大的病毒网站,他有着好多好多

hdu 3065 病毒侵袭持续中 AC自动机模板题 ,,一A。

病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7685    Accepted Submission(s): 2687 Problem Description 小t非常感谢大家帮忙解决了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的"万恶之源".这是一个庞大的病毒网站,他有着好多好多

HDU 3065 病毒侵袭持续中 AC自动机

HDU 3065 AC自动机 这个也可以拿来做模板了,使用静态数组模拟建树 1 //#pragma comment(linker, "/STACK:1677721600") 2 #include <map> 3 #include <set> 4 #include <stack> 5 #include <queue> 6 #include <cmath> 7 #include <ctime> 8 #include &

hdu 3056 病毒侵袭持续中 AC自动机

http://acm.hdu.edu.cn/showproblem.php?pid=3065 刘汝佳的模板真的很好用,这道题直接过 学到: cnt数组记录单词出现次数 以及map存储单词编号与字符串,便于处理相关信息 上代码: #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <queue> #include <str

hdoj 3065 病毒侵袭持续中(AC自动机)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3065 思路分析:问题需要模式匹配多个模式串,需要注意的是模式串会包含和重叠,需要对AC自动机的匹配过程进行修改,对于每个节点,需要从该节点的失败指针回溯, 如果失败指针回溯后的节点为某个模式串的最后一个节点,则匹配了另一个模式串: 代码如下: #include <queue> #include <cstdio> #include <cstring> #include &l

HDU 3065 病毒侵袭持续中(AC自动机)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3065 Problem Description 小t非常感谢大家帮忙解决了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的"万恶之源".这是一个庞大的病毒网站,他有着好多好多的病毒,但是这个网站包含的病毒很奇怪,这些病毒的特征码很短,而且只包含"英文大写字符".当然小t好想好想为民除害,但是小t从来不打没有准备的战争.知己知彼,百战不殆,小t首先要

HDU 3065 病毒侵袭持续中 (AC自动机)

题目链接:病毒侵袭持续中 解析:用end数组标记病毒编号,用used数组记录各个病毒出现的次数,最后对应输出即可. AC代码: #include <bits/stdc++.h> using namespace std; const int maxn = 1002; const int max_word = 52; const int max_text = 2000002; const int sigma_size = 128; char buf[max_text], vir[maxn][max

HDU 3065 病毒侵袭持续中(AC自己主动机)

题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=3065 Problem Description 小t非常感谢大家帮忙攻克了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的"万恶之源".这是一个庞大的病毒站点,他有着好多好多的病毒.可是这个站点包括的病毒非常奇怪,这些病毒的特征码非常短,并且仅仅包括"英文大写字符".当然小t好想好想为民除害,可是小t从来不打没有准备的战争.知己知彼,百战不殆.小

hdu3065 病毒侵袭持续中 AC自动机入门题 N(N &lt;= 1000)个长度不大于50的模式串(保证所有的模式串都不相同), 一个长度不大于2000000的待匹配串,求模式串在待匹配串中的出现次数。

/** 题目:hdu3065 病毒侵袭持续中 链接:http://acm.hdu.edu.cn/showproblem.php?pid=3065 题意:N(N <= 1000)个长度不大于50的模式串(保证所有的模式串都不相同), 一个长度不大于2000000的待匹配串,求模式串在待匹配串中的出现次数. 思路:ac自动机做发,val标记每一个病毒串编号,通过print函数统计每一个病毒出现的次数. AC自动机好文章:http://www.cppblog.com/menjitianya/archi