HDU 3065 病毒侵袭持续中

来源:互联网 发布:crocs淘宝正品店 编辑:程序博客网 时间:2024/05/02 06:10

询问每个模式串在文本传中出现的次数。

文本串中出现的字符不一定都是大写字母,只需要在匹配的时候,对文本串进行特殊处理,将连续的大写字母段当成合法的一个文本串即可。

然后……就是简单的统计了。





#include <cstdio>#include <algorithm>#include <vector>#include <queue>#include <cstring>#include <string>using namespace std;int n, cnt[1010];char s[1010][55], t[2000010], a[2000010];struct AC_Automata {    #define N 60003    #define M 26    int ch[N][M], f[N], val[N], last[N], sz;    void clear() { sz = 1; memset(ch[0], 0, sizeof(ch[0])); }    int idx(char c) { return c-'A'; }    void insert(char s[], int v) {        int u = 0;        for (int i=0; s[i]; i++) {            int c = idx(s[i]);            if (!ch[u][c]) {                memset(ch[sz], 0, sizeof(ch[sz]));                val[sz] = 0;                ch[u][c] = sz++;            }            u = ch[u][c];        }        val[u] = v;    }    void build() {        queue<int> q;        f[0] = 0;        for (int c=0; c<M; c++) {            int u = ch[0][c];            if (u) { f[u] = last[u] = 0; q.push(u); }        }        while (!q.empty()) {            int r = q.front(); q.pop();            for (int c=0; c<M; c++) {                int u = ch[r][c];                if (!u) { ch[r][c] = ch[f[r]][c]; continue; }                q.push(u);                f[u] = ch[f[r]][c];                last[u] = val[f[u]] ? f[u] : last[f[u]];            }        }    }    void find(char s[]) {        int j = 0;        for (int i=0; s[i]; i++) {            int c = idx(s[i]);            j = ch[j][c];            if (val[j]) print(j);            else if (last[j]) print(last[j]);        }    }    void print(int j) {        if (j) {            cnt[val[j]]++;            print(last[j]);        }    }} ac;int main() {#ifndef ONLINE_JUDGE    freopen("in.txt", "r", stdin);#endif    while (scanf(" %d", &n) == 1) {        ac.clear();        memset(cnt, 0, sizeof(cnt));        getchar();        for (int i=1; i<=n; i++) {            gets(s[i]); ac.insert(s[i], i);        }        ac.build();        gets(t);        int j = 0;        bool flag = false;        for (int i=0; t[i]; i++) {            if (t[i] <= 'Z' && t[i] >= 'A') { flag = true; a[j++] = t[i]; }            else if (flag) {                a[j] = 0; j = 0;                flag = false;                ac.find(a);            }        }        if (flag) {            a[j] = 0; j = 0;            flag = false; ac.find(a);        }        for (int i=1; i<=n; i++)            if (cnt[i]) printf("%s: %d\n", s[i], cnt[i]);    }    return 0;}


原创粉丝点击