Keywords Search hdu2222 ac自动机

来源:互联网 发布:软件导刊 核心期刊 编辑:程序博客网 时间:2024/04/30 11:37

Description


给定T组数据n个单词一个字符串s求s中有多少给出的单词出现

Solution


无力吐槽题号

ac自动机裸题模板,学习了
所谓ac自动机就是一棵带fail指针的trie,t(i)的fail表示作为t(i)后缀的另一字符串的前缀位置,然后这个fail是可以bfs出来的

还有就是最好记路strlen不然每次会TLE。神奇

辣鸡csdn卡死害我重写了三遍

为了应对MLE这里补上指针版本的

Code


#include <stdio.h>#include <string.h>#include <queue>#define rep(i, st, ed) for (int i = st; i <= ed; i += 1)#define fill(x, t) memset(x, t, sizeof(x))#define N 500005#define L 27using namespace std;int rc[N][L], p[N], f[N], cnt, len;char s[1000001];inline void getFail(){    queue<int> q;    rep(i, 'a', 'z'){        if (rc[0][i - 'a']){            q.push(rc[0][i - 'a']);        }    }    while (!q.empty()){        int now = q.front(); q.pop();        rep(i, 'a', 'z'){            if (rc[now][i - 'a']){                q.push(rc[now][i - 'a']);                int v = f[now];                while (v && !rc[v][i - 'a']){                    v = f[v];                }                f[rc[now][i - 'a']] = rc[v][i - 'a'];            }        }    }}inline void insert(){    int now = 0;    rep(i, 0, len - 1){        int tar = s[i] - 'a';        if (!rc[now][tar]){            rc[now][tar] = ++ cnt;        }        now = rc[now][tar];    }    p[now] += 1;}inline void query(){    int now = 0;    int ans = 0;    rep(i, 0, len - 1){        int tar = s[i] - 'a';        while (now && !rc[now][tar]){            now = f[now];        }        now = rc[now][tar];        for (int tmp = now; tmp; tmp = f[tmp]){            ans += p[tmp];            p[tmp] = 0;        }    }    printf("%d\n", ans);}int main(void){    int T;    scanf("%d", &T);    while (T --){        cnt = 0;        fill(rc, 0);        fill(f, 0);        fill(p, 0);        int n;        scanf("%d", &n);        rep(i, 1, n){            scanf("%s", s);            len = strlen(s);            insert();        }        getFail();        scanf("%s", s);        len = strlen(s);        query();    }    return 0;}
#include <stdio.h>#include <string.h>#include <queue>#define rep(i, st, ed) for (int i = st; i <= ed; i += 1)#define fill(x, t) memset(x, t, sizeof(x))#define N 1001001struct node{    node *next[26];    node *fail;    int count;    node(){        fail = NULL;        rep(i, 0, 25){            next[i] = NULL;        }        count = 0;    }}*root;inline void ins(char *str){    node *now = root;    int len = strlen(str);    rep(i, 0, len - 1){        int tar = str[i] - 'a';        if (now->next[tar] == NULL){            now->next[tar] = new node();        }        now = now->next[tar];    }    now->count += 1;}using std:: queue;queue<struct node *> que;inline void getFail(){    int head = 0, tail = 0;    que.push(root);    while (!que.empty()){        node *now = que.front(); que.pop();        rep(i, 0, 25){            if (now->next[i] != NULL){                if (now == root){                    now->next[i]->fail = root;                }else{                    node *tmp = now->fail;                    while (tmp != NULL){                        if (tmp->next[i] != NULL){                            now->next[i]->fail = tmp->next[i];                            break;                        }                        tmp = tmp->fail;                    }                    if (tmp == NULL){                        now->next[i]->fail = root;                    }                }                que.push(now->next[i]);            }        }    }}inline int query(char *str){    int len = strlen(str);    int ret = 0;    node *now = root;    rep(i, 0, len - 1){        int tar = str[i] - 'a';        while (now->next[tar] == NULL && now != root){            now = now->fail;        }        now = now->next[tar];        if (now == NULL){            now = root;        }        node *tmp = now;        while (tmp != root && tmp->count != -1){            ret += tmp->count;            tmp->count = -1;            tmp = tmp->fail;        }    }    return ret;}char str[N];int main(void){    int T;    scanf("%d", &T);    while (T --){        int n;        scanf("%d", &n);        root = new node();        rep(i, 1, n){            scanf("%s", str);            ins(str);        }        scanf("%s", str);        getFail();        int ans = query(str);        printf("%d\n", ans);    }    return 0;}
1 0
原创粉丝点击