题意 就是给你 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;
}