HDU2896

来源:互联网 发布:网络红歌2016火爆歌曲 编辑:程序博客网 时间:2024/05/29 18:42

病毒侵袭

题目链接

分类data structures strings

1.题意概述

  • 给你N(1<=N<=500)个模式串,M(1<=M<=1000)个待匹配串,查询这M个串每个串中模式串出现过哪几个,和总的出现次数。

2.解题思路

  • 也是裸的AC自动机,因为是有查询几次,为了方便输出,我们插入同时维护记录一下插入的每个模式串的id和次数。

3.AC代码

class Trie {public:#define tot_len 100010#define tot_ch 130#define CUR s[i]    int next[tot_len][tot_ch], fail[tot_len], end[tot_len];    bool used[510];    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]);                }            }        }    }    bool Query(char *s, int n, int id) {        int len = strlen(s);        int now = root;        memset(used, 0, sizeof used);        bool flag = 0;        rep(i, 0, len) {            now = next[now][CUR];            int tmp = now;            while (tmp != root) {                if (end[tmp] != -1) {                    used[end[tmp]] = 1;                    flag = 1;                }                tmp = fail[tmp];            }        }        if (!flag) return 0;        printf("web %d:", id);        rep(i, 1, n + 1) if (used[i]) printf(" %d", i);        puts("");        return 1;    }#undef CUR#undef tot_ch#undef tot_len} AC;char ch[maxn], key[291];inline void solve() {    int n, m;    while (~scanf("%d", &n)) {        AC.Init();        rep(i, 1, n + 1) {            scanf("%s", key);            AC.Insert(key, i);        }        AC.Build();        int ans = 0;        scanf("%d", &m);        rep(i, 1, m + 1) {            scanf("%s", ch);            if (AC.Query(ch, n, i))                ans++;        }        printf("total: %d\n", ans);    }}
原创粉丝点击