#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string>
#include <queue>
#include <cstring>
#include <map>
#define N 200005
using namespace std;
struct AC{
int tot,ch[N][26],fail[N],ed[N],val[N];
AC(){
tot=0;
memset(ch,-1,sizeof(ch));
memset(fail,0,sizeof(fail));
memset(ed,0,sizeof(ed));
memset(val,0,sizeof(val));
}
void ins(int num,string s){
int now=0;
for(int i=0;i<s.size();++i){
if(ch[now][s[i]-'a']==-1)
ch[now][s[i]-'a']=++tot;
now=ch[now][s[i]-'a'];
}
ed[now]=num;
}
void get_fail(){
queue<int> l;
for(int i=0;i<26;++i){
if(ch[0][i]!=-1){
l.push(ch[0][i]);
}
}
while(!l.empty()){
int u=l.front();
l.pop();
for(int i=0;i<26;++i){
if(ch[u][i]!=-1){
fail[ch[u][i]]=max(ch[fail[u]][i],0);
l.push(ch[u][i]);
}
else{
ch[u][i]=ch[fail[u]][i];
}
}
}
}
void query(string s){
int now=0;
for(int i=0;i<s.size();++i){
now=ch[now][s[i]-'a'];
if(now==-1)
now=0;
for(int j=now;j&&j!=-1;j=fail[j]){
++val[ed[j]];
}
}
}
}zdj;
int n,m;
string read(){
char c=getchar();
while(c<'a'||c>'z')
c=getchar();
string s="";
while(c>='a'&&c<='z'){
s+=c;
c=getchar();
}
return s;
}
struct node{
string s;
int id;
bool operator <(const node &b)const{
return s<b.s;
}
}s[N];
string t;
int shang[N],ans[N];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i){
s[i].s=read();
s[i].id=i;
}
sort(s+1,s+n+1);
int lst=1;
zdj.ins(1,s[1].s);
for(int i=2;i<=n;++i){
if(s[i].s==s[lst].s){
shang[i]=lst;
}
else{
zdj.ins(i,s[i].s);
lst=i;
}
}
zdj.get_fail();
t=read();
zdj.query(t);
for(int i=1;i<=n;++i){
if(!shang[i])
ans[s[i].id]=zdj.val[i];
else
ans[s[i].id]=zdj.val[shang[i]];
}
for(int i=1;i<=n;++i){
printf("%d\n",ans[i]);
}
return 0;
}
/*
*/
可能是我处理同样的字符串的地方很复杂,有没有大佬帮我看一下