网址:https://vjudge.net/problem/HDU-2896
题意:
给出$n$个模式串和$m$个文本串,求文本串中出现的模式串的编号。注意:字符集为可见字符。
题解:
$AC$自动机模板题,参考本博客的$HDU2222$的题解。网址:https://www.cnblogs.com/Aya-Uchida/p/11560405.html。
AC代码:
#include <iostream> #include <queue> #include <algorithm> #include <vector> #include <cstring> #include <string> using namespace std; #define maxn 200005 int trie[maxn][130],fail[maxn],cntword[maxn],cnt=0,strid=0; bool strext[505],flag; struct AC { void insert(string &str) { int next,root=0; for(int i=0;i<str.size();++i) { next=str[i]; if(!trie[root][next]) trie[root][next]=++cnt; root=trie[root][next]; } cntword[root]=++strid; } void buildfail() { queue<int>que; for(int i=0;i<130;++i) { if(trie[0][i]) { fail[trie[0][i]]=0; que.push(trie[0][i]); } } while(!que.empty()) { int now = que.front(); que.pop(); for(int i=0;i<130;++i) { if(trie[now][i]) { fail[trie[now][i]]=trie[fail[now]][i]; que.push(trie[now][i]); } else trie[now][i]=trie[fail[now]][i]; } } } void query(string &str) { flag=0; int ans=0,now=0; for(int i=0;i<str.size();++i) { now=trie[now][str[i]]; for(int j=now;j;j=fail[j]) { //cout<<cntword[j]<<endl; strext[cntword[j]]=1; } } } }; int main() { ios::sync_with_stdio(0); string tmp; int n; cin>>n; AC ac; for(int i=0;i<n;++i) { cin>>tmp; ac.insert(tmp); } ac.buildfail(); int m; cin>>m; int tot=0; for(int i=0;i<m;++i) { cin>>tmp; memset(strext,0,sizeof(strext)); ac.query(tmp); for(int j=1;j<=n;++j) { //cout<<strext[j]<<endl; if(strext[j]) { if(!flag) { cout<<"web "<<i+1<<":"; flag=1; } cout<<" "<<j; } } if(flag) { ++tot; cout<<endl; } } cout<<"total: "<<tot<<endl; return 0; }