- 建立trie
- 建立fail指针
- 差分求个数
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e6+500;
int n;
int trie[maxn][30],tot,fail[maxn];
int nxt[maxn],id[maxn],d[maxn],ans[maxn],q[maxn];
char str[maxn];
void insert(char* str, int idx){
int len = strlen(str), rt = 0;
for(int i=0;i<len;i++){
int nx = str[i]-'a';
if(!trie[rt][nx]) trie[rt][nx] = ++tot;
rt = trie[rt][nx];
}
nxt[idx] = id[rt];
id[rt] = idx;
}
void build(){
int head=1, tail = 0;
for(int i=0;i<30;i++) if(trie[0][i]) q[++tail] = trie[0][i];
while(head<=tail){
int now = q[head++];
for(int i=0;i<26;i++){
if(trie[now][i])
fail[trie[now][i]] = trie[fail[now]][i], q[++tail] = trie[now][i];
else
trie[now][i] = trie[fail[now]][i];
}
}
}
void solve(){
scanf("%s",str);
int len = strlen(str);
for(int i=0,rt=0;i<len;i++)
rt = trie[rt][str[i]-'a'], d[rt]++;
for(int i=tot;i;i--){
for(int j=id[q[i]];j;j=nxt[j])
ans[j] = d[q[i]];
d[fail[q[i]]]+=d[q[i]];
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",str);
insert(str,i);
}
build();
solve();
for(int i=1;i<=n;i++)
printf("%d\n",ans[i]);
return 0;
}