zoukankan      html  css  js  c++  java
  • HDU 2896 病毒侵袭 [AC自动机]

    http://acm.hdu.edu.cn/showproblem.php?pid=2896

    题意:给n个模式串m个文本串,问每个文本串里出现了哪些模式串。每个模式串唯一。

    ac自动机中,用end数组把模式串的id记录下来就好。

    #include<cassert>
    #include<algorithm>
    #include<cmath>
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<set>
    #include<queue>
    #include<map>
    using namespace std;
    #define rep(i,f,t) for(int i = (f), _end = (t); i <= _end; ++i)
    #define dep(i,f,t) for(int i = (f), _end = (t); i >= _end; --i)
    #define clr(c,x) memset(c,x,sizeof(c));
    #define debug(x) cout<<"debug  "<<x<<endl;
    const int INF = 0x3f3f3f3f;
    typedef long long int64;
    
    inline int RD(){ int res; scanf("%d",&res); return res; }
    
    #define Rush for(int casn = RD(), cas = 1; cas <= casn; ++cas)
    
    //*******************************************************************************
    
    const int maxn = 501;
    struct Trie{
        int next[maxn*200][128];
        int fail[maxn*200];
        int end[maxn*200];
        int sz;
        void init(){
            sz = 0;
            clr(next[0],0);
        }
        int newnode(){
            ++sz;
            clr(next[sz],0);
            fail[sz] = end[sz] = 0;
            return sz;
        }
        void insert(char *s, int id){
            int u = 0;
            while(*s){
                int &v = next[u][*s];
                if(!v) v = newnode();
                u = v;
                ++s;
            }
            end[u] = id;
        }
        void build(){
            queue<int> Q;
            rep(i,1,127){
                if(next[0][i])Q.push(next[0][i]);
            }
            while(!Q.empty()){
                int u = Q.front();
                Q.pop();
                int fu = fail[u];
                rep(c,1,127){
                    int &v = next[u][c];
                    if(v){
                        Q.push(v);
                        fail[v] = next[fu][c];
                    }else{
                        v = next[fu][c];
                    }
                }
            }
        }
        void query(char *s, vector<int> &res){
            int u = 0;
            while(*s){
                u = next[u][*s];
                int k = u;
                while(k){
                    if(end[k]){
                        res.push_back(end[k]);
                    }
                    k = fail[k];
                }
                ++s;
            }
            sort(res.begin(),res.end());
        }
    }ac;
    
    char str[10005];
    int main(){
        int n,m;
        while(~scanf("%d",&n)){
            ac.init();
            rep(i,1,n){
                scanf("%s",str);
                ac.insert(str,i);
            }
            ac.build();
            scanf("%d",&m);
            vector<int> res;
            int tot = 0;
            rep(i,1,m){
                scanf("%s",str);
                res.clear();
                ac.query(str,res);
                if(!res.empty()){
                    ++tot;
                    printf("web %d:",i);
                    rep(j,0,res.size()-1){
                        printf(" %d",res[j]);
                    }
                    printf("
    ");
                }
            }
            printf("total: %d
    ",tot);
        }
        return 0;
    }

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    操作系统之进程篇(3)
    指针和数组及内存管理
    进程篇(3: 基本进程控制:进程的退出)--请参照本博客“操作系统”专栏
    Java面向对象程序设计--泛型编程
    进程篇(1: 进程运行环境)--请参照本博客“操作系统”专栏
    操作系统之进程篇(1)
    分类器性能指标之ROC曲线、AUC值
    如何理解似然函数?
    sigmoid函数简介
    Hive分析窗口函数
  • 原文地址:https://www.cnblogs.com/DSChan/p/4861971.html
Copyright © 2011-2022 走看看