hdu5384(2015多校8)--Danganronpa(AC自动机)

题目链接:点击打开链接

题目大意:给出n个字符串主串,和m个模式串,定义f(A,B)为B串在A串中出现的次数,现在对每一个A串都计算

∑f(Ai,Bj) (1 <= j <= m),并输出。

对m个模式串建立AC自动机,然后每个主串都放入自动机中,统计主串包含多少B内的串,并输出。

注意:

标记的时候直接累加值,可能会有多个模式串相同。

统计的时候,使用fail一直要回到根。

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std ;
#define LL __int64
#pragma comment(linker, "/STACK:102400000,102400000")
struct node
{
    int data ;
    node *next[26] , *fail ;
};
string str[10010] , s ;
LL sum ;
queue <node*> que ;
node *newnode()
{
    node *p = new node ;
    p->data = 0 ;
    p->fail = NULL ;
    for( int i = 0 ; i < 26 ; i++)
        p->next[i] = NULL ;
    return p ;
}
void settree(node *rt)
{
    int i , k , l = s.size() ;
    node *p = rt ;
    for(i = 0 ; i < l ; i++)
    {
        k = s[i] - 'a' ;
        if( p->next[k] == NULL )
            p->next[k] = newnode() ;
        p = p->next[k] ;
    }
    p->data++ ;
}
void setfail(node *rt)
{
    int i ;
    node *p , *temp ;
    while( !que.empty() ) que.pop() ;
    que.push(rt) ;
    while( !que.empty() )
    {
        p = que.front() ;
        que.pop() ;
        for(i = 0 ; i < 26 ; i++)
        {
            if( p->next[i] )
            {
                temp = p->fail ;
                while( temp && !temp->next[i] )
                    temp = temp->fail ;
                p->next[i]->fail = temp ? temp->next[i] : rt ;
                que.push(p->next[i]) ;
            }
            else
                p->next[i] = p == rt ? rt : p->fail->next[i] ;
        }
    }
    return ;
}
void query(int u,node *rt)
{
    int i , k , l = str[u].size() ;
    node *p = rt , *temp ;
    for(i = 0 ; i < l ; i++)
    {
        if( str[u][i] < 'a' || str[u][i] > 'z' )
        {
            p = rt ;
            continue ;
        }
        k = str[u][i] - 'a' ;
        p = p->next[k] ;
        for( temp = p ; temp ; temp = temp->fail ) {
            sum += temp->data ;
        }
    }
    return ;
}
int main()
{
    int n , m , i , t ;
    node *rt ;
    scanf("%d", &t) ;
    while( t-- ) {
        rt = newnode() ;
        scanf("%d %d", &n, &m) ;
        for(i = 0 ; i < n ; i++)
            cin >> str[i] ;
        for(i = 0 ; i < m ; i++) {
            cin >> s ;
            settree(rt) ;
        }
        setfail(rt) ;
        for(i = 0 ; i < n ; i++) {
            sum = 0 ;
            query(i,rt) ;
            printf("%I64d\n", sum) ;
        }
    }
    return 0;
}


你可能感兴趣的:(hdu5384(2015多校8)--Danganronpa(AC自动机))