AC自動機 [模板]
阿新 • • 發佈:2018-12-15
#include<cstdio> #include<string> #include<cstring> #include<queue> #include<iostream> #define N 500050 using namespace std; int fail[N],ch[N][26],cnt[N]; int T,n,tot=1; void Init(){ memset(fail,0,sizeof(fail)); memset(ch,0,sizeof(ch)); memset(cnt,0,sizeof(cnt)); tot = 1; } void Insert(string s){ int len = s.length(); int now = 1; for(int i=0;i<len;i++){ int x = s[i] - 'a'; if(!ch[now][x]) ch[now][x] = ++tot; now = ch[now][x]; } cnt[now]++; } void build(){ queue<int> q; q.push(1); while(!q.empty()){ int x = q.front(); q.pop(); for(int i=0;i<26;i++) if(ch[x][i]){ if(x==1) fail[ch[x][i]] = 1; else{ int x1 = fail[x]; for(; x1; x1=fail[x1]) if(ch[x1][i]){ fail[ch[x][i]] = ch[x1][i]; break; } if(x1==0) fail[ch[x][i]] = 1; } q.push(ch[x][i]); } } } int quary(string s){ int len = s.length(); int now = 1 , ans = 0; for(int i=0;i<len;i++){ int x = s[i] - 'a'; while(!ch[now][x] && now!=1) now = fail[now]; if(ch[now][x]==0) continue; now = ch[now][x]; for(int j=now ;j != 1 && cnt[j] != -1; j = fail[j]){ ans += cnt[j] , cnt[j] = -1; } } return ans; } int main(){ scanf("%d",&T); while(T--){ scanf("%d",&n); Init(); for(int i=1;i<=n;i++){ string s; cin>>s; Insert(s); } build(); string s; cin>>s; printf("%d\n",quary(s)); } return 0; }