题目链接:Keywords Search
题意:T组数据,每组数据n个单词,一个串,问串中出现了几个单词。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<set>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = 5e5+10;
int n;
int fail[N];
int word[N];
int trie[N][26], tot;
void ins(char *s)
{
int root = 0;
int len = strlen(s);
for(int i = 0; i < len; i++)
{
int now = s[i]-'a';
if(!trie[root][now])
{
trie[root][now] = ++tot;
}
root = trie[root][now];
}
word[root]++;
}
void get_fail()
{
queue<int> q;
for(int i = 0; i < 26; i++)
{
if(trie[0][i])
{
fail[trie[0][i]] = 0;
q.push(trie[0][i]);
}
}
while(!q.empty())
{
int now = q.front();
q.pop();
for(int i = 0; i < 26; i++)
{
if(trie[now][i])
{
fail[trie[now][i]] = trie[fail[now]][i];
q.push(trie[now][i]);
}
else
trie[now][i] = trie[fail[now]][i];
}
}
}
int query(char *s)
{
int now = 0, ans = 0;
int len = strlen(s);
for(int i = 0; i < len; i++)
{
now = trie[now][s[i]-'a'];
for(int j = now; j && word[j] != -1; j = fail[j])
{
ans += word[j];
word[j] = -1;
}
}
return ans;
}
int main()
{
int t;
char s[1000010];
scanf("%d", &t);
while(t--)
{
tot = 0;
memset(trie, 0, sizeof(trie));
memset(word, 0, sizeof(word));
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
scanf("%s", s);
ins(s);
}
fail[0] = 0;
get_fail();
scanf("%s", s);
printf("%d\n", query(s));
}
return 0;
}