zoukankan      html  css  js  c++  java
  • hdu 3065 病毒侵袭持续中【AC自动机】

    <题目链接>

    题目大意:

    小t非常感谢大家帮忙解决了他的上一个问题。然而病毒侵袭持续中。在小t的不懈努力下,他发现了网路中的“万恶之源”。这是一个庞大的病毒网站,他有着好多好多的病毒,但是这个网站包含的病毒很奇怪,这些病毒的特征码很短,而且只包含“英文大写字符”。当然小t好想好想为民除害,但是小t从来不打没有准备的战争。知己知彼,百战不殆,小t首先要做的是知道这个病毒网站特征:包含多少不同的病毒,每种病毒出现了多少次。大家能再帮帮他吗?
    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 55*1000;
    int n,num[1005];
    char words[1005][55];
    
    struct Trie{
        int nxt[N][128],fail[N],end[N];
        int root,pos;
        int newnode(){
            for(int i=0;i<128;i++)
                nxt[pos][i]=-1;
            end[pos++]=0;
            return pos-1;
        }
        void init(){
            pos=0;root=newnode();
        }
        void insert(char s[],int id){
            int len=strlen(s);
            int now=root;
            for(int i=0;i<len;i++){
                int to=s[i];
                if(nxt[now][to] == -1)
                    nxt[now][to]=newnode();
                now=nxt[now][to];
            }
            end[now]=id;
        }
        void build(){
            fail[root]=root;
            queue<int>q;
            for(int i=0;i<128;i++){
                if(nxt[root][i]==-1)
                    nxt[root][i]=root;
                else{
                    fail[nxt[root][i]]=root;
                    q.push(nxt[root][i]);
                }
            }
            while(!q.empty()){
                int now=q.front();q.pop();
                for(int i=0;i<128;i++){
                    if(nxt[now][i]==-1)
                        nxt[now][i]=nxt[fail[now]][i];
                    else{
                        fail[nxt[now][i]]=nxt[fail[now]][i];
                        q.push(nxt[now][i]);
                    }
                }
            }
        }
        void query(char s[]){
            int len=strlen(s);
            int now=root;
            for(int i=0;i<len;i++){
                now=nxt[now][s[i]];
                int tmp=now;
                while(tmp!=root){
                    if(end[tmp]!=0)
                        num[end[tmp]]++;
                    //若每个模式串只在主串中匹配一次则加上 end[temp]=0; 
                    tmp=fail[tmp];
                }
            }
            for(int i=1;i<=n;i++)
                if(num[i]!=0)
                    printf("%s: %d
    ",words[i],num[i]);
        }
    }ac;
    
    char buf[int(2e6+5)];
    int main(){
        while(~scanf("%d",&n)){
            memset(num,0,sizeof(num));
            ac.init();
            for(int i=1;i<=n;i++){
                scanf("%s",words[i]);
                ac.insert(words[i],i);
            }
            ac.build();
            scanf("%s",buf);
            ac.query(buf);
        }
    }
  • 相关阅读:
    struts2校验器
    Struts2 验证框架 validation.xml 常用的验证规则
    MVC 无法找到资源
    架构设计
    金山西山居初赛第二场 美素数
    K Smallest Sums
    金山游戏编程复赛 连续最大积
    C++大作业之链表实现的高精度加法,减法,和数组实现的高精度乘法。
    POJ 3250 Bad Hair Day
    PoJ2492A Bug's Life并查集
  • 原文地址:https://www.cnblogs.com/00isok/p/9428706.html
Copyright © 2011-2022 走看看