题意:给你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. 设计模式之抽象工厂模式(Java实现)

    “上次是我的不对,贿赂作者让我先讲来着,不过老婆大人大人有大量,不与我计较,这次还让我先把上次未讲完的应用场景部分给补充上去,有妻如此,夫复何求.”(说完,摸了摸跪的发疼的膝盖,咳咳,我发四我没笑!真 ...

  2. thinkphp---手机访问切换模板!

    手机访问切换模板:一般用在手机在做自适应的情况. 第一步:需要添加判断是否是手机访问的方法: http://www.cnblogs.com/e0yu/p/7561811.html 第二步:Home / ...

  3. oneThink的ArticleController控制,详看

    本人新手小白,看下 onethink 的 ArticleController , 它里面写的方法,和一些自己以后改进的方向: <?php namespace Home\Controller; c ...

  4. Morris InOrder Traverse Binary Tree 无需使用递归和栈

    今天在切leetcode的时候看到一个Morris算法,用来中序遍历二叉树,非递归,O(1)空间.觉得很强大.记录一下. 基本思想是利用了Threaded Binary Tree. 步骤如下: cur ...

  5. [Jenkins] 批量删除构建历史

    Manage Jenkins -> Script Console def jobName = "Some_Job_Name" def maxNumber = 64 Jenki ...

  6. Elasticsearch之settings和mappings(图文详解)

    Elasticsearch之settings和mappings的意义 简单的说,就是 settings是修改分片和副本数的. mappings是修改字段和类型的. 记住,可以用url方式来操作它们,也 ...

  7. python https协议和InsecurePlatformWarning问题

    本人最近在学习python,今天想使用python来抓取糗事百科网站上的一些笑话故事的,由于糗事百科的网站url采取的是https协议,所以当我按照常规的方式抓取的时候,发现不行,报错了,找了很多方法 ...

  8. Supermarket---poj456(贪心并查集优化)

    题目链接:http://poj.org/problem?id=1456 题意是现有n个物品,每个物品有一个保质期和一个利润,现在每天只能卖一个商品,问最大的利润是多少,商品如果过期了就不能卖了: 暴力 ...

  9. Linux内核之vmlinux与vmlinuz

    因为是初次系统的学习Linux内核,过程中遇到了一些常常出现的名词.似曾相识,但对他们的含义又不是非常清楚.因此,将搜索到的内容进行一下汇总. 1.vmlinux   vmlinux是一个包括linu ...

  10. Ambari Rest api 使用

    最近由于项目的需要在看一些Ambari的api去获取集群的一些信息,获取集群节点的状态信息以及各个服务和组件的信息.然后在我们的数据服务管理平台上去做一些监控运维,现在把一些使用总结一下:官网rest ...