#hihocoder 1036 trie图

来源:互联网 发布:js二维数组不合法的是 编辑:程序博客网 时间:2024/06/02 07:30

题意:

本质是在前缀trie树上,加上每个节点的后继边,变成trie图来完成AC自动机的匹配。

#include <cstdio>#include <queue>#include <cstring>#include <iostream>#include <algorithm>#include <string>#include <cmath>using namespace std;#define pr(x) cout << #x << ": " << x << "  " #define pl(x) cout << #x << ": " << x << endl;const int maxn = 1e6 + 13;const int maxtrie = 1000 * 1000 + 12; //注意这里为最多500个单词,每个单词最多500个字母,所以节点最多为乘const int maxcharset = 26; //字符集合const char charst = 'a'; //起始字符char buf[maxn];bool ok = false;struct Trie{    int next[maxtrie][maxcharset], fail[maxtrie], end[maxtrie];    int root, L;    int newnode(void) {        for (int i = 0;i < maxcharset;i++) next[L][i] = -1;        end[L++] = 0;        return L - 1;    }    void init(void) {        L = 0;        root = newnode();    }    void insert(char buf[]) {        int len = (int)strlen(buf);        int now = root;        for(int i = 0;i < len;i++) {            if(next[now][buf[i] - charst] == -1)                next[now][buf[i] - charst] = newnode();            now = next[now][buf[i] - charst];        }        end[now]++;    }    void build(void) {        queue<int> Q;        fail[root] = root;        for(int i = 0;i < maxcharset;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 < maxcharset;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]);                }        }    }    //返回模式串中有多少个在buf中出现过。    int query(char buf[])    {        int len = strlen(buf), now = root, ret = 0;        for(int i = 0;i < len;i++) {            now = next[now][buf[i] - charst];            ret += end[now];        }        return ret;    }}ac;int main(){#ifdef xiaoai    freopen("in.txt", "r", stdin);    //freopen("out.txt", "w", stdout);#endif    int n;    scanf("%d", &n);    ac.init();    while (n--) {        scanf("%s", buf);        ac.insert(buf);    }    ac.build();    scanf("%s", buf);    ok =  ac.query(buf);    puts(ok ? "YES" : "NO");    return 0;}
0 0
原创粉丝点击