题目:给你一个目标串,和一些模式串,问每个模式串是否在目标串中出现。
分析:字符串,AC自动机。一开始用KMP算法,TLE了才发现会超时,改用AC自动机;
直接利用AC自动机存储,查询即可,然后按顺序输出;
如果模式串中有重复的,直接利用并查集合并即可,只须判断父节点。
说明:╮(╯▽╰)╭计算复杂度时,数据组数被忽略了;注意初始化。
#include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> using namespace std; char s[100002],t[1002]; #define nodesize 40004 //节点个数 #define dictsize 52 //字符集大小 typedef struct node1 { int flag; //值域 node1* fail; node1* next[dictsize]; }tnode; tnode dict[nodesize+1]; tnode* Q[nodesize+1]; int ID[256]; int visit[1002]; int father[1002]; class AC_DFA { private: int size; tnode* root; public: AC_DFA() {makeID();init();} void makeID() { for ( int i = 0 ; i < 26 ; ++ i ) { ID['a'+i] = i; ID['A'+i] = i+26; } } void init() { memset( dict, 0, sizeof( dict ) ); root=NULL; size=0; root=newnode(); for ( int i = 0 ; i < 1001 ; ++ i ) father[i] = i; } tnode* newnode() { dict[size].fail = root; return &dict[size ++]; } void insert( char* word, int id ) { tnode* now = root; for ( int i = 0 ; word[i] ; ++ i ) { if ( !now->next[ID[word[i]]] ) now->next[ID[word[i]]] = newnode(); now = now->next[ID[word[i]]]; } if ( now->flag ) father[id] = now->flag; else now->flag = id; } void setfail() { Q[0] = root; root->fail = NULL; for ( int move = 0,save = 1 ; move < save ; ++ move ) { tnode* now = Q[move]; for ( int i = 0 ; i < dictsize ; ++ i ) if ( now->next[i] ) { tnode* p = now->fail; while ( p && !p->next[i] ) p = p->fail; now->next[i]->fail = p?p->next[i]:root; Q[save ++] = now->next[i]; } } } void query( char* line, int q ) { memset( visit, 0, sizeof( visit ) ); tnode* now = root; for ( int i = 0 ; line[i] ; ++ i ) { while ( now && !now->next[ID[line[i]]] ) now = now->fail; now = now?now->next[ID[line[i]]]:root; for ( tnode* p = now ; p ; p = p->fail ) visit[p->flag] = 1; } for ( int i = 1 ; i <= q ; ++ i ) if ( visit[father[i]] ) printf("y\n"); else printf("n\n"); return; } }dfa; /* AC_DFA end */ int main() { int k,q; scanf("%d",&k); while ( k -- ) { dfa.init(); scanf("%s%d",s,&q); for ( int i = 1 ; i <= q ; ++ i ) { scanf("%s",t); dfa.insert( t, i ); } dfa.setfail(); dfa.query(s, q); } return 0; }
UVa 10679 - I Love Strings!!,布布扣,bubuko.com
原文地址:http://blog.csdn.net/mobius_strip/article/details/36866517