HDU 3065 病毒侵袭持续中

来源:互联网 发布:rt809编程器使用方法 编辑:程序博客网 时间:2024/05/02 01:00

AC自动机模板题。感觉数据略水。从2896改过来的

#include<cstdio>#include<string>#include<cstring>#include<cmath>#include<algorithm>#include<iostream>using namespace std;#define N 2000005char a[1005][55];char b[N];int n, m;int sum;struct Trie {    Trie *fail;    Trie *son[26];    int ex;};Trie t[N];Trie *que[N];int num[1005];int ptr;Trie *NewNode(){    Trie *p = &t[ptr++];    memset(p->son, NULL, sizeof(p->son));    p->fail = NULL;    p->ex = 0;    return p;}void Insert(int id, Trie *root){    Trie *tmp = root;    for(int i = 0; a[id][i]; i++){        if(tmp->son[a[id][i] - 'A'] == NULL)            tmp->son[a[id][i] - 'A'] = NewNode();        tmp = tmp->son[a[id][i] - 'A'];    }    tmp->ex = id;}void gfail(Trie *root){    int head = 0, tail = 0;    que[tail++] = root;    Trie *tmp;    while(head < tail){        tmp = que[head++];        for(int i = 0; i < 26; i++){            if(tmp->son[i] != NULL){                Trie *next = tmp->fail;                while(next != NULL && next->son[i] == NULL){                    next = next->fail;                }                if(next == NULL)                    tmp->son[i]->fail = root;                else                    tmp->son[i]->fail = next->son[i];                que[tail++] = tmp->son[i];            }        }    }}void AC(Trie *root){    Trie *tmp = root;    for(int i = 0; b[i]; i++){        if(b[i] < 'A' || b[i] > 'Z')tmp = root;        else {            while(tmp->son[b[i] - 'A'] == NULL && tmp != root){                tmp = tmp->fail;            }            if(tmp->son[b[i] - 'A'] == NULL)                tmp = root;            else                tmp = tmp->son[b[i] - 'A'];        }        Trie *p = tmp;        while(p != root){            num[p->ex]++;            p = p->fail;        }    }}int main(){    while(scanf("%d", &n) != EOF){        memset(num, 0, sizeof(num));        sum = 0;        ptr = 0;        Trie *root = NewNode();        for(int i = 1; i <= n; i++){            scanf("%s", a[i]);            Insert(i, root);        }        gfail(root);        scanf("%s", b);        AC(root);        for(int i = 1; i <= n; i++){            if(num[i])printf("%s: %d\n", a[i], num[i]);        }    }    return 0;}


0 0