传送门
题意
给定(N)个字符串,(S_{1}、S_{2}、dots S_{N}),(M)个询问,每次询问给定一个字符串(T),求出在(S_{1}、S_{2}、dots S_{N})中有多少是(T)的子串
数据范围
字符串你的总长度(leq 10^{6})
题解
先将所有的字符串插入字典树之中,然后对每次给定的字符串(T),进行查询操作,累计以其中每个字符结尾的字符串个数即可、
- 注意第一个节点也就是根是空节点
Code
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=a;i--)
const int N=1e5+10;
int trie[N][26],cnt[N],tot=1;
char s[N];
void insert(char s[])
{
int p=1;
for(int i=0;s[i];i++)
{
int c=s[i]-'a';
if(!trie[p][c]) trie[p][c]=++tot;
p=trie[p][c];
}
cnt[p]++;
}
int query(char s[])
{
int res=0,p=1;
for(int i=0;s[i];i++)
{
int c=s[i]-'a';
if(!trie[p][c]) return res;
p=trie[p][c];
res+=cnt[p];
}
return res;
}
void solve()
{
int n,m;
cin>>n>>m;
while(n--)
{
cin>>s;
insert(s);
}
while(m--)
{
cin>>s;
cout<<query(s)<<endl;
}
}
int main()
{
solve();
return 0;
}