Link:http://acm.split.hdu.edu.cn/showproblem.php?pid=5880
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1000110;
int len[N];
int res[N];
struct Aho
{
struct Node{
int nex[26];
int fail,endd;
}node[N];
int Size;
queue<int> que;
int newnode(){
for(int i = 0; i < 26; i++)
node[Size].nex[i] = 0;
node[Size].fail = node[Size].endd = 0;
return Size++;
}
void init(){
while(que.size()) que.pop();
Size = 0;
newnode();
}
void Insert(char *s,int id)
{
int L = len[id];
int now = 0;
for(int i = 0; i < L; i++){
int x = s[i]-'a';
if(node[now].nex[x]==0)
node[now].nex[x]=newnode();
now = node[now].nex[x];
}
node[now].endd = id;
}
void build()
{
node[0].fail = 0;
for(int i = 0; i < 26; i++)
{
if(node[0].nex[i])
{
node[node[0].nex[i]].fail = 0;
que.push(node[0].nex[i]);
}
}
while(que.size())
{
int u = que.front();
que.pop();
for(int i = 0; i < 26; i++)
{
if(node[u].nex[i]==0)
node[u].nex[i] = node[node[u].fail].nex[i];
else
{
node[node[u].nex[i]].fail = node[node[u].fail].nex[i];
que.push(node[u].nex[i]);
}
}
}
}
int pos[N];
void marth(char *s)
{
memset(pos,0,sizeof(pos));
int L = strlen(s);
int now = 0;
for(int i = 0; i < L; i++)
{
int x;
if(s[i] >= 'a' && s[i] <= 'z')
x = s[i]-'a';
else if(s[i] >= 'A' && s[i] <= 'Z')
x = s[i]-'A';
else
continue;
now = node[now].nex[x];
int temp = now;
while(temp)
{
if(node[temp].endd)
{
pos[i+1]-=1;
pos[i-len[node[temp].endd]+1]+=1;
}
temp = node[temp].fail;
}
}
long long cnt=0;
for(int i=0;i<L;i++)
{
cnt+=pos[i];
if(cnt<=0) printf("%c",s[i]);
else printf("*");
}
puts("");
}
}aho;
char s[N];
int main()
{
int T,n;
scanf("%d",&T);
while(T--)
{
aho.init();
scanf("%d",&n);
for(int i = 1; i <= n; i++){
scanf("%s",s);
len[i] = strlen(s);
aho.Insert(s,i);
}
aho.build();
getchar();
gets(s);
// printf("%s\n",s);
aho.marth(s);
}
return 0;
}