题意:给你n个模式串,再给你m个主串,问你每个主串中有多少模式串,并输出是哪些。注意一下,这里给的字符范围是可见字符0~127,所以要开130左右。

思路:用字典树开的时候储存编号,匹配完成后set记录保证不重复和排序。

代码:

#include<cstdio>
#include<vector>
#include<set>
#include<queue>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#define ll long long
const int maxn = 5000000+5;
const int maxm = 100000+5;
const int MOD = 1e7;
const int INF = 0x3f3f3f3f;
const int kind = 130;
const char baset = 0;
using namespace std;
struct Trie{
    Trie *next[kind];
    Trie *fail; //失配值
    int sum;    //以此为单词结尾的个数
    int id;
    Trie(){
        sum = 0;
        memset(next,NULL,sizeof(next));
        fail = NULL;
        id = 0;
    }
};
Trie *root;
queue<Trie *> Q;
int head,tail;
set<int> record;
void Insert(char *s,int id){
    Trie *p = root;
    for(int i = 0;s[i];i++){
        int x = s[i] - baset;
        if(p ->next[x] == NULL){
            p ->next[x] = new Trie();
        }
        p = p ->next[x];
    }
    p ->sum++;
    p ->id = id;
}
void buildFail(){   //计算失配值
    while(!Q.empty()) Q.pop();
    Q.push(root);
    Trie *p,*temp;
    while(!Q.empty()){
        temp = Q.front();
        Q.pop();
        for(int i = 0;i < kind;i++){
            if(temp ->next[i]){
                if(temp == root){   //父节点为root,fail为root
                    temp ->next[i] ->fail = root;
                }
                else{
                    p = temp ->fail;    //查看父节点的fail
                    while(p){
                        if(p ->next[i]){
                            temp ->next[i] ->fail = p ->next[i];
                            break;
                        }
                        p = p ->fail;
                    }
                    if(p == NULL) temp ->next[i] ->fail = root;
                }
                Q.push(temp ->next[i]);
            }
        }
    }
}
void ac_automation(char *ch){
    //p为模式串指针
    Trie *p = root;
    int len = strlen(ch);
    for(int i = 0;i < len;i++){
        int x = ch[i] - baset;
        while(!p ->next[x] && p != root)
            p = p ->fail;
        p = p ->next[x];    //找到后p指针指向该结点
        if(!p) p = root;    //若指针返回为空,则没有找到与之匹配的字符
        Trie *temp = p;
        while(temp != root){
            if(temp ->id > 0)
                record.insert(temp ->id);
            temp = temp ->fail;
        }
    }
}
char ch[210];
char s[10005];
int main(){
    int n,m,x;
    root = new Trie();
    scanf("%d",&n);
    for(int i = 1;i <= n;i++){
        scanf("%s",ch);
        Insert(ch,i);
    }
    buildFail();
    int tot = 0;
    scanf("%d",&m);
    for(int i = 1;i <= m;i++){
        record.clear();
        scanf("%s",s);
        ac_automation(s);
        if(record.size()){
            tot++;
            printf("web %d:",i);
            int End = record.size();
            for(int j = 1;j <= End;j++){
                int id = *record.begin();
                printf(" %d",id);
                record.erase(id);
            }
            printf("\n");
        }
    }
    printf("total: %d\n",tot);
    return 0;
}

HDU 2896 病毒侵袭(AC自动机)题解的更多相关文章

  1. hdu 2896 病毒侵袭 ac自动机

    /* hdu 2896 病毒侵袭 ac自动机 从题意得知,模式串中没有重复的串出现,所以结构体中可以将last[](后缀链接)数组去掉 last[]数组主要是记录具有相同后缀模式串的末尾节点编号 .本 ...

  2. hdu 2896 病毒侵袭 AC自动机(查找包含哪些子串)

    病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  3. hdu 2896 病毒侵袭 AC自动机 基础题

    病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  4. HDU 2896 病毒侵袭 (AC自己主动机)

    pid=2896">http://acm.hdu.edu.cn/showproblem.php?pid=2896 病毒侵袭 Time Limit: 2000/1000 MS (Java ...

  5. hdu 2896 病毒侵袭_ac自动机

    题意:略 思路:套用ac自动机模板 #include <iostream> #include<cstdio> #include<cstring> using nam ...

  6. HDU 2896 病毒侵袭 AC自己主动机题解

    本题是在text里面查找key word的增强版.由于这里有多个text. 那么就不能够简单把Trie的叶子标志记录改动成-1进行加速了,能够使用其它技术.我直接使用个vis数组记录已经訪问过的节点, ...

  7. HDU 2896 病毒侵袭(AC自动机水)

    病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  8. HDU 2896 病毒侵袭(AC自动机)

    病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  9. HDU 2896 病毒侵袭【AC自动机】

    <题目链接> Problem Description 当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻....在这样的时刻,人们却异常兴奋——我们能在有生之年看到500年一 ...

  10. hdu2896 病毒侵袭 ac自动机

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=2896 题目: 病毒侵袭 Time Limit: 2000/1000 MS (Java/Othe ...

随机推荐

  1. SPF难以解决邮件伪造的现状以及方案

    邮件伪造的现状 仿冒域名 私搭邮服仿冒域名: 例如某公司企业的域名是example.com,那么攻击者可以搭建一个邮服,也把自己的域名配置为example.com,然后发邮件给真实的企业员工xxx@e ...

  2. String() 函数把对象的值转换为字符串。

    var test1 = new Boolean(1);var test2 = new Boolean(0);var test3 = new Boolean(true);var test4 = new ...

  3. [MongoDB]安装MongoDB遇到问题

    1. 首先,当然是下载 MongoDB MongoDB的官方网站是:http://www.mongodb.org/, 最新版本下载在:http://www.mongodb.org/downloads  ...

  4. log buffer space事件(转)

    看了这篇文章: Oracle常见的等待事件说明http://database.ctocio.com.cn/tips/38/6669538.shtml 对于Log Buffer Space-日志缓冲空间 ...

  5. 微信小程序 --- 动画

    动画的基本使用: 旋转动画 缩放动画 偏移动画 倾斜动画 矩阵动画 动画API:wx.createAnimation(object) 示例:创建一个点击的动画 <view class=" ...

  6. Jenkins升级、迁移、备份

    1.升级 下载新版Jenkins.war文件,替换旧版本war文件,重启即可. Jenkins.war文件的位置一般为/usr/lib/jenkins/Jenkins.war. 2.迁移.备份 Jen ...

  7. 牛客网多校赛第七场J--Sudoku Subrectangle

    链接:https://www.nowcoder.com/acm/contest/145/J 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言6553 ...

  8. 解决 Ubuntu 下 Sublime Text 无法输入中文的问题

    解决 Ubuntu 下 Sublime Text 无法输入中文的问题 1. 安装依赖库 sudo apt-get install build-essential sudo apt-get instal ...

  9. Grafana+Prometheus监控

    添加模板一定要看说明以及依赖 监控redis https://blog.52itstyle.com/archives/2049/ http://www.cnblogs.com/sfnz/p/65669 ...

  10. B. Factory Repairs---cf627B(线段树)

    题目链接:http://codeforces.com/problemset/problem/627/B 题意:有一个工厂生产零件,但是机器是不正常的,需要维修,维修时间是 k 天,在维修期间不能生产, ...