HDU 2896 病毒侵袭(AC自动机裸)

来源:互联网 发布:dosci 科研数据平台 编辑:程序博客网 时间:2024/05/16 06:23

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2896

题意:先给出n个模式串,然后给出m个文本串,求每个文本串包含多少个模式串。

思路:AC自动机裸题。

代码:

#include <iostream>#include <stdio.h>#include <string.h>#include <math.h>#include <algorithm>#include <string>#include <vector>#include <map>#include <queue>#include <stack>using namespace std;#define lson l, m, rt << 1#define rson m + 1, r, rt << 1 | 1#define ceil(x, y) (((x) + (y) - 1) / (y))const int SIZE = 1e2;const int N = 1e5 + 10;const int M = 1e4 + 10;const int INF = 0x7f7f7f7f;const int MAX_WORD = 2e2 + 10;const double EPS = 1e-9;const int MOD = 2015;int sz, q;int ch[N][SIZE];int f[N];int ed[N];bool vis[N];int vir[M][10];char str[MAX_WORD];char txt[M];int newnode() {    memset(ch[sz], 0, sizeof(ch[sz]));    f[sz] = 0;    ed[sz] = 0;    return sz++;}void init() {    sz = 0;    q = 0;    newnode();}void insert(char *s, int id) {    int u = 0;    for (int i = 0; s[i]; i++) {        int v = s[i] - 32;        if (!ch[u][v])            ch[u][v] = newnode();        u = ch[u][v];    }    ed[u] = id;}void getfail() {    queue<int> q;    for (int i = 0; i < SIZE; i++)        if (ch[0][i])            q.push(ch[0][i]);    while (!q.empty()) {        int r = q.front();        q.pop();        for (int i = 0; i < SIZE; i++) {            int v = ch[r][i];            if (v) {                q.push(v);                int u = f[r];                while (u && !ch[u][i]) u = f[u];                f[v] = ch[u][i];            }            else ch[r][i] = ch[f[r]][i];        }    }}void find(char *s, int id) {    int u = 0;    vir[q][0] = 2;    for (int i = 0; s[i]; i++) {        int v = s[i] - 32;        u = ch[u][v];        int p = u;        while (p && !vis[p]) {            if (ed[p]) {                vir[q][1] = id;                vir[q][vir[q][0]] = ed[p];                vir[q][0]++;                vis[p] = true;            }            p = f[p];        }    }    if (vir[q][0] > 2)        q++;}int main() {        int n, m;    while (scanf("%d", &n) != EOF) {        init();        getchar();        for (int i = 1; i <= n; i++) {            gets(str);            insert(str, i);        }        memset(vir, 0, sizeof(vir));        scanf("%d", &m);        getfail();        getchar();        for (int i = 1; i <= m; i++) {            memset(vis, false, sizeof(vis));            gets(txt);            find(txt, i);        }        for (int i = 0; i < q; i++) {            printf("web %d: ", vir[i][1]);            sort(&vir[i][2], &vir[i][vir[i][0]]);            for (int j = 2; j < vir[i][0] - 1; j++)                printf("%d ", vir[i][j]);            printf("%d\n", vir[i][vir[i][0] - 1]);        }        printf("total: %d\n", q);    }    return 0;}
0 0