zoukankan      html  css  js  c++  java
  • HDU 2222 Keywords Search [AC自动机]

    http://acm.hdu.edu.cn/showproblem.php?pid=2222
    题意:给一堆模式串和一个文本串,问有多少个模式串在文本串中出现过。

    AC自动机,在统计答案的时候记得将end清零就好

    #include<queue>
    #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 = 10005;
    struct Trie{
        int next[maxn*50][26];
        int fail[maxn*50];
        int end[maxn*50];
        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 u = 0;
            while(*s){
                int nid = *s++ - 'a';
                if(!next[u][nid]){
                    next[u][nid] = newnode();
                }
                u = next[u][nid];
            }
            ++end[u];
        }
    
        void build(){
            queue<int> Q;
            int u = 0;
            rep(c,0,25){
                if(next[0][c]){
                    Q.push(next[0][c]);
                }
            }
            while(!Q.empty()){
                u = Q.front();
                Q.pop();
                int fu = fail[u];
                rep(c,0,25){
                    int v = next[u][c];
                    if(v){
                        Q.push(v);
                        fail[v] = next[fu][c];
                    }else{
                        next[u][c] = next[fu][c];
                    }
                }
            }
        }
    
        int query(char *s){
            int u = 0;
            int ans = 0;
            while(*s){
                int nid = *s++ - 'a';
                u = next[u][nid];
                int k = u;
                while(k){
                    if(end[k]){
                        ans += end[k];
                        end[k] = 0;
                    }
                    k = fail[k];
                }
            }
            return ans;
        }
    }ac;
    char str[1000009];
    int main(){
        Rush{
            ac.init();
            int n;
            scanf("%d",&n);
            while(n--){
                scanf("%s",str);
                ac.insert(str);
            }
            ac.build();
            scanf("%s",str);
            printf("%d
    ",ac.query(str));
        }
        return 0;
    }

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

  • 相关阅读:
    php-fpm 启动参数及重要配置详解
    Linux系统优化实现高并发
    Linux下php-fpm进程过多导致内存耗尽问题
    .htaccess详解及.htaccess参数说明
    添加PHP扩展模块
    nginx 服务器重启命令,关闭
    linux的文件打包与压缩
    vue 存取、设置、清除cookie
    div轮流滚动显示
    滚动监听
  • 原文地址:https://www.cnblogs.com/DSChan/p/4861972.html
Copyright © 2011-2022 走看看