题意:
题意:给出n个串,然后给一篇文章,问这n个串有多少个在文章里面出现过。。。
trick:n个串可能有相同的,需按照不同串处理。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <list>
#include <queue>
#include <map>
#include <stack>
using namespace std;
#define L(i) i<<1
#define R(i) i<<1|1
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-3
#define maxn 1000010
#define MOD 100000000
char str[maxn];
struct node
{
int count;
struct node *next[26];
struct node *fail;
void init()
{
for(int i = 0; i < 26; i++)
next[i] = NULL;
count = 0;
fail = NULL;
}
}*root;
void insert()
{
node *p = root;
int len = strlen(str);
for(int i = 0; i < len; i++)
{
int pos = str[i] - 'a';
if(p->next[pos] == NULL)
{
p->next[pos] = new node;
p->next[pos]->init();
p = p->next[pos];
}
else
p = p->next[pos];
}
p->count++;
}
void getfail()
{
node *p = root,*son,*temp;
queue<struct node *> que;
que.push(p);
while(!que.empty())
{
temp = que.front();
que.pop();
for(int i = 0; i < 26; i++)
{
son = temp->next[i];
if(son != NULL)
{
if(temp == root)
son->fail = root;
else
{
p = temp->fail;
while(p)
{
if(p->next[i])
{
son->fail = p->next[i];
break;
}
p = p->fail;
}
if(!p)
son->fail = root;
}
que.push(son);
}
}
}
}
void query()
{
int cnt = 0;
int len = strlen(str);
node *p = root,*temp;
for(int i = 0; i < len; i++)
{
int pos = str[i] - 'a';
while(!p->next[pos] && p != root)
p = p->fail;
p = p->next[pos];
if(!p)
p = root;
temp = p;
while(temp != root)
{
if(temp->count >= 0)
{
cnt += temp->count;
temp->count = -1;
}
else
break;
temp = temp->fail;
}
}
printf("%d\n",cnt);
}
int main()
{
int T,n;
scanf("%d",&T);
while(T--)
{
root = new node;
root->init();
root->fail = NULL;
scanf("%d",&n);
for(int i = 0; i < n; i++)
{
scanf("%s",str);
insert();
}
getfail();
scanf("%s",str);
query();
}
return 0;
}