HDU2222

来源:互联网 发布:爆菊 知乎 编辑:程序博客网 时间:2024/05/29 10:51

Keywords Search

题目链接

分类data structures strings

1.题意概述

  • 给你N(N <= 10000)个模式串和一个待匹配串,现在问你待匹配串中出现过几种模式串?

2.解题思路

  • 裸的AC自动机,因为问的是出现过几次,所以标记策略是每一类的最后一个位置置1,Query时候访问过一个种类就注意置0!

3.AC代码

class Trie {public:#define tot_len 500010#define tot_ch 26#define CUR (s[i] - 'a')    int next[tot_len][tot_ch], fail[tot_len], end[tot_len];    int root, L;    int Newnode() {        rep(i, 0, tot_ch) next[L][i] = -1;        end[L++] = 0;        return L - 1;    }    void Init() {        L = 0;        root = Newnode();    }    void Insert(char *s, int val) {        int len = strlen(s);        int now = root;        rep(i, 0, len) {            if (next[now][CUR] == -1)                next[now][CUR] = Newnode();            now = next[now][CUR];        }        end[now] += val;    }    void Build() {        queue<int> q;        fail[root] = root;        rep(i, 0, tot_ch) {            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();            rep(i, 0, tot_ch) {                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 *s) {        int len = strlen(s);        int now = root, ans = 0;        rep(i, 0, len) {            now = next[now][CUR];            for (int j = now; j != root && end[j]; j = fail[j]) {                ans += end[j];                end[j] = 0;            }        }        return ans;    }#undef CUR#undef tot_ch#undef tot_len} AC;char ch[maxn], key[51];inline void solve() {    int t, n;    scanf("%d", &t);    while (t--) {        AC.Init();        scanf("%d", &n);        rep(i, 0, n) {            scanf("%s", key);            AC.Insert(key, 1);        }        AC.Build();        scanf("%s", ch);        printf("%d\n", AC.Query(ch));    }}
原创粉丝点击