题解:
问加入的字符串中有多少是当前给出的字符串的前缀子串,那么我们就可以对每一个加入的字符串建立Trie树,然后只需要把最后的End
数组改一下意义就可以,因为统计的是前缀数目,那我们就把每一个作为结尾的节点数目记录一下,然后当我们发现这个节点是作为结尾的时候,让ans
进行一次累加即可
AC代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<stack>
#include<queue>
#include<bitset>
#include<list>
#include<limits.h>
#define ll long long
#define INF 1e12
#define inf -1e12
#define me(a,b) memset(a,b,sizeof(a))
#define PII pair<int,int>
#define ull unsigned long long
#define ios std :: ios :: sync_with_stdio(false)
using namespace std;
const int maxn = 1e6 + 19;
int trie[maxn][26] = {},n,m,tot = 1;
int End[maxn] = {};
char str[maxn];
void insert(char * str)
{
int len = strlen(str),p = 1;
for(int k = 0;k < len;k++){
int ch = str[k] - 'a';
if(trie[p][ch] == 0) trie[p][ch] = ++tot;
p = trie[p][ch];
}
End[p] ++;
}
int Search(char * str)
{
int len = strlen(str),p = 1,ans = 0;
for(int k = 0;k < len;k++){
p = trie[p][str[k] - 'a'];
if(End[p]) ans += End[p];
}
return ans;
}
int main()
{
ios;
cin >> n >> m;
for(int i = 0;i < n;i++){
cin >> str;
insert(str);
}
for(int i = 0;i < m;i++){
cin >> str;
cout << Search(str) << endl;
}
return 0;
}