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