HDU 2222 Keywords Search [AC自动机]

来源:互联网 发布:淘宝店客服怎么设置 编辑:程序博客网 时间:2024/06/08 01:02

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\n",ac.query(str));    }    return 0;}
0 0
原创粉丝点击