HDU2222 AC自动机

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct node {
    int cnt;
    node * fail;
    node * nxt[26];
}*q[500400], pool[500300];
node * root;
char t[1002000], w[1020];
int sz;
node* creat() {
    node * p = &pool[sz++];
    memset( p, 0, sizeof( node ) );
    return p;
}
void insert( char * s ) {
    node *p = root;
    int n = strlen( s );
    for( int i = 0; i < n; ++i ) {
        int c = s[i] - 'a';
        if( p -> nxt[c] == NULL ) {
            p -> nxt[c] = creat();
        }
        p = p -> nxt[c];
    }
    p -> cnt++;
}
void build_ac() {
    int head, tail;
    head = tail = 0;
    q[tail++] = root;
    while( head < tail ) {
        node *p = q[head++];
        for( int i = 0; i < 26; ++i ) {
            if( p -> nxt[i] == NULL )
                continue;
            node *v = p -> fail;
            while( v && v -> nxt[i] == NULL )
                v = v -> fail;
            if( ! v )
                p -> nxt[i] -> fail = root;
            else
                p -> nxt[i] -> fail = v -> nxt[i];
            q[tail++] = p -> nxt[i];
        }
    }
}
int query() {
    int n = strlen( t );
    int ret = 0;
    node *p = root;
    for( int i = 0; i < n; ++i ) {
        int c = t[i] - 'a';
        while( p -> nxt[c] == NULL && p != root ) {
            p = p -> fail;
        }
        p = p -> nxt[c];
        if( p == NULL )
            p = root;
        node *temp = p;
        while( temp != root && temp -> cnt != -1 ) {
            ret += temp -> cnt;
            temp -> cnt = -1;
            temp = temp -> fail;
        }
    }
    return ret;
}
int main() {
    int cas;
    scanf( "%d", &cas );
    while( cas-- ) {
        int n;
        sz = 0;
        root = creat();
        scanf( "%d", &n );
        while( n-- ) {
            scanf( "%s", w );
            insert( w );
        }
        build_ac();
        scanf( "%s", t );
        printf( "%d\n", query() );
    }
    return 0;
}

你可能感兴趣的:(HDU2222 AC自动机)