HDU3065

来源:互联网 发布:java里氏替换原则 编辑:程序博客网 时间:2024/05/13 17:25

病毒侵袭持续中

题目链接

分类data structures strings

1.题意概述

  • 给你N(1<=N<=1000)个模式串,再给你一个病毒串,问这些模式串分别出现过几次?

2.解题思路

  • AC自动机裸题,直接插入时候维护每个串ID,再开一个cnt[i]数组维护第i个模式串出现次数即可。

3.AC代码

char str[1001][60];class Trie {public:#define tot_len 120010#define tot_ch 130#define CUR s[i]    int next[tot_len][tot_ch], fail[tot_len], end[tot_len], cnt[2000];    int root, L;    int Newnode() {        rep(i, 0, tot_ch) next[L][i] = -1;        end[L++] = -1;        return L - 1;    }    void Init() {        L = 0;        root = Newnode();    }    void Insert(char *s, int id) {        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] = id;    }    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]);                }            }        }    }    void Query(char *s, int n) {        int len = strlen(s);        int now = root;        memset(cnt, 0, sizeof cnt);        rep(i, 0, len) {            now = next[now][CUR];            int tmp = now;            while (tmp != root) {                if (end[tmp] != -1)                    cnt[end[tmp]]++;                tmp = fail[tmp];            }        }        rep(i, 0, n) if (cnt[i]) printf("%s: %d\n", str[i], cnt[i]);    }#undef CUR#undef tot_ch#undef tot_len} AC;char ch[2000001];inline void solve() {    int n;    while (~scanf("%d", &n)) {        AC.Init();        rep(i, 0, n) {            scanf("%s", str[i]);            AC.Insert(str[i], i);        }        AC.Build();        scanf("%s", ch);        AC.Query(ch, n);    }}