USETC 1821 AC 自动机

题意   就是给你  N 个病毒,求有多少字串不包含病毒串; abc  病毒   aabcd  算包含病毒

方法   传递最小值

#include<iostream>  
#include<stdio.h>  
#include<cstring>  
#include<algorithm>  
using namespace std;  
  
char str[1123456],cha[112345];  
long long head,tail,total;  
struct date  
{  
    date *fail,*next[26];  
    long long len;  
}tree[112345],*que[112345],*root;  
date *creat_node()  
{  
    for( int i = 0; i < 26; i++ )  
    tree[total].next[i] = NULL;  
    tree[total].fail    = NULL;  
    tree[total].len     = (1<<30);   
    return &tree[total++];  
}  
void inint()  
{  
    head = tail = total = 0;  
    root = creat_node();  
    root->fail = root;  
}  
void insert( char *word,int len )  
{  
    date *temp = root;  
    while( *word )  
    {  
        int num = *word - 'a';  
        if( temp->next[num] == NULL )  
            temp->next[num] = creat_node();  
        temp = temp->next[num];  
        word++;  
    }   
    temp->len  =  len;  
}  
void build_AC( )  
{  
    que[tail++] = root;  
    while( tail > head )  
    {  
        date *temp = que[head++];  
        for( int i = 0; i < 26; i++ )  
        if( temp->next[i] != NULL )  
        {  
            if( temp == root )  
                 temp->next[i]->fail = root;  
            else temp->next[i]->fail = temp->fail->next[i];  
                temp->next[i]->len  = min( temp->fail->next[i]->len,temp->next[i]->len );  
            que[tail++] = temp->next[i];  
        }  
        else  
        {  
            if( temp == root )  temp->next[i] = root;  
            else                temp->next[i] = temp->fail->next[i];  
        }  
    }  
}  
long long work( )  
{  
    date *temp = root;  
    long long len = -1,pos = -1,ans = 0;  
    while( str[++len] )  
    {  
        int num = str[len] - 'a';  
        temp = temp->next[num];  
        if( temp->len - 1 < len - pos )  
        {  
            ans = ans + temp->len - 1;  
            pos = len - temp->len + 1;  
        }  
        else ans = ans + len - pos;  
    }  
    return ans;  
}  
int main( )  
{  
    int T,i,N,cas = 1;  
    scanf("%d",&T);  
    while( T-- )  
    {  
        scanf("%s%d",&str,&N);inint( );  
        for( i = 0; i < N; i++ )  
        {  
            scanf("%s",&cha);  
            insert( cha,strlen(cha) );  
        }  
            build_AC();  
        printf("Case #%d: %lld\n",cas++,work());  
    }  
    return 0;  
}  

  

原文地址:https://www.cnblogs.com/wulangzhou/p/3044579.html