题意:给你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. MQTT协议笔记之mqtt.io项目TCP协议支持

    前言 MQTT定义了物联网传输协议,其标准倾向于原始TCP实现.构建于TCP的上层协议堆栈,诸如HTTP等,在空间上多了一些处理路径,稍微耗费了CPU和内存,虽看似微乎其微,但对很多处理能力不足的嵌入 ...

  2. 【jdk源码学习】HashMap

    package com.emsn.crazyjdk.java.util; /** * “人”类,重写了equals和hashcode方法...,以id来区分不同的人,你懂的... * * @autho ...

  3. 正则表达式—RegEx(RegularExpressio)(二)

    今日随笔,继续写一些关于正则表达式的东西. 首先补一点昨天的内容: 昨天少说了一个贪婪模式,什么是贪婪模式,比如像+或者*这样的元字符匹配中,会以最大匹配值匹配,这句话是什么意思呢,例如: 定义一个正 ...

  4. Unity3D笔记三 物理引擎

    一.物理引擎 1.物理引擎就是模拟真实世界中物体碰撞.跌落等反应,通过Ballance.愤怒的小鸟来理解什么是物理引擎.Unity的物理引擎使用的是NviDIA的PhysX.2.选中一个游戏对象,主菜 ...

  5. Spring AOP依赖包

    Spring4和2.5发生了很大的变化,原来的spring2.5很多倚赖的jar包都是随着spring一起发布的,现在spring4已 经不再发布倚赖包,需要你自己去导入 1.org.springfr ...

  6. 170607、SQL Select语句完整的执行顺序

    SQL Select语句完整的执行顺序: 1.from子句组装来自不同数据源的数据: 2.where子句基于指定的条件对记录行进行筛选: 3.group by子句将数据划分为多个分组: 4.使用聚集函 ...

  7. CodeForces 651 C Watchmen

    C. Watchmen time limit per test 3 seconds memory limit per test 256 megabytes input standard input o ...

  8. 洛谷P2444 病毒【AC自动机】

    题目描述 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会已经找出了所有的病毒代码段,试问,是否 ...

  9. 聊一聊goroutine stack

    通过阅读这篇文章对内存的处理以及栈的扩容有了新的认识,我们在生产环境中也遇到了内存使用量超大的情况,现在怀疑也可能是由于栈扩容导致的 很好的一片文章: 推送在外卖订餐中扮演着重要的角色,为商家实时接单 ...

  10. Mongo副本集的配置以及php node.js连接使用副本集

    最近弄了下mongodb的副本集, 首先说下没有认证情况的副本集,相对比较简单,因为环境有限,我在同一台服务器上做了模拟. --rest参数是打开web监控页面,比如我们这里监听37017端口,则打开 ...