HDU 2222 Keywords Search (AC自动机)

来源:互联网 发布:gps网络平台网址 编辑:程序博客网 时间:2024/04/30 19:28

题目链接:Keywords Search


解析:直接开个end数组,统计一下即可。

PS:AC自动机的代码风格是参考bin神的。



AC代码:

#include <bits/stdc++.h>using namespace std;const int max_word = 500005;const int sigma_size = 26;const int max_text = 1000005;struct Trie{    int next[max_word][sigma_size], fail[max_word], end[max_word];    int root, L;    int newnode(){        for(int i = 0; i < sigma_size; i++) next[L][i] = -1;        end[L++] = 0;        return L-1;    }    void init(){        L = 0;        root = newnode();    }    void insert(char buf[]){        int len = strlen(buf);        int now = root;        for(int i = 0; i < len; i++){            if(next[now][buf[i] - 'a'] == -1) next[now][buf[i] - 'a'] = newnode();            now = next[now][buf[i] - 'a'];        }        end[now] ++;    }    void build(){        queue<int> Q;        fail[root] = root;        for(int i = 0; i < sigma_size; i++){            if(next[root][i] == -1) next[root][i] = root;            else{                fail[ next[root][i] ] = root;                Q.push(next[root][i]);            }        }        while(!Q.empty()){            int now = Q.front();            Q.pop();            for(int i = 0; i < sigma_size; i++){                if(next[now][i] == -1) next[now][i] = next[ fail[now] ][i];                else{                    fail[ next[now][i] ] = next[ fail[now] ][i];                    Q.push(next[now][i]);                }            }        }    }    int query(char buf[]){        int len = strlen(buf);        int now = root;        int res = 0;        for(int i = 0; i < len; i++){            now = next[now][ buf[i] - 'a' ];            int temp = now;            while(temp != root){                res += end[temp];                end[temp] = 0;                temp = fail[temp];            }        }        return res;    }    void debug(){        for(int i = 0; i < L; i++){            printf("id = %3d, fail = %3d, end = %3d, chi = [", i, fail[i], end[i]);            for(int j = 0; j < sigma_size; j++) printf("%2d", next[i][j]);            printf("]\n");        }    }};char buf[max_text];Trie ac;int main(){    #ifdef sxk        freopen("in.txt", "r", stdin);    #endif // sxk    int T, n;    scanf("%d", &T);    while(T--){        scanf("%d", &n);        ac.init();        for(int i = 0; i < n; i++){            scanf("%s", buf);            ac.insert(buf);        }        ac.build();        scanf("%s", buf);        printf("%d\n", ac.query(buf));    }    return 0;}





0 0
原创粉丝点击