hdu 2222 AC自动机

来源:互联网 发布:ubuntu nfs配置 编辑:程序博客网 时间:2024/05/02 09:31

http://acm.hdu.edu.cn/showproblem.php?pid=2222

就是裸的多串匹配的问题,AC自动机模板题

http://www.cppblog.com/MatoNo1/archive/2011/10/19/158635.html

用了yang_7_46的模板

#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <string>#include <queue>#include <map>#include <iostream>#include <algorithm>using namespace std;#define RD(x) scanf("%d",&x)#define RD2(x,y) scanf("%d%d",&x,&y)#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)#define clr0(x) memset(x,0,sizeof(x))#define eps 1e-9const double pi = acos(-1.0);typedef long long LL;const int modo = 1e9 + 7;const int maxn = 1e6 + 5,maxm = 1e4 + 5;int cnt;struct AC_Automata {    #define N 240005    #define M 26    int ch[N][M], sz;    int val[N], last[N], f[N], cc[N];    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] = cc[sz] = 0;                ch[u][c] = sz++;            }            u = ch[u][c];        }        cc[u]++;        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] = 0, q.push(u); last[u] = 0; }        }        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);                int v = f[r];                f[u] = ch[v][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]);            if (cc[j]) print(j);            else if (last[j]) print(last[j]);        }    }    void print(int j) { //打印以结点j结尾的所有字符串        if (j) {            //printf("%d: %d\n", j, val[j]);            cnt += cc[j];            cc[j] = 0;            print(last[j]);        }    }} ac;char s[55], text[1000006];int main() {    int n, _;    RD(_);    while (_--) {        RD(n);        ac.clear();        for (int i=1; i<=n; i++) {            scanf(" %s", s); ac.insert(s, i);        }        ac.build();        cnt = 0;        scanf(" %s", text);        ac.find(text);        printf("%d\n", cnt);    }    return 0;}


0 0