题目描述
解析
(没有做出来,这个ans的处理方式其实也不难想…qwq)
考虑把T都作为模板串加入trie树
加入每个模板串自然就是按照i顺序的
所以我们在插入t的时候沿途标记一下
新出现的未标记的i的间隔就是当前的i与上一次的标记的差-1
在其中一直取max即可得到最大间隔
不要忘记还有一个间隔是n-最后的标记值!
预处理完trie树后就简单了
让s在trie树上跑,跑到尾就返回尾的ans值即可
如果跑一半失配了说明没有t符合条件,直接返回n即可
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
typedef unsigned long long ull;
const int N = 6e6+100;
const int M=1e6+10;
const ll mod=199907210507;
int n,m;
int tr[N][4],tot=1,ans[N],id[N];
char s[N];
void build(int k){
int l=strlen(s+1),p=1;
for(int i=1;i<=l;i++){
int a=s[i]-'a'+1;
if(!tr[p][a]) tr[p][a]=++tot;
p=tr[p][a];
ans[p]=max(ans[p],k-id[p]-1);
id[p]=k;
}
}
int ask(){
int l=strlen(s+1),p=1;
for(int i=1;i<=l;i++){
int a=s[i]-'a'+1;
if(!tr[p][a]) return n;
p=tr[p][a];
}
return ans[p];
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf(" %s",s+1);
build(i);
}
for(int i=1;i<=tot;i++){
ans[i]=max(ans[i],n-id[i]);
}
for(int i=1;i<=m;i++){
scanf(" %s",s+1);
printf("%d\n",ask());
}
return 0;
}
/*
9 6 10
5 6 2 10 10 7 3 2 9
1 4 4 3 2 1
6 4 10
3 5 2 7 1 9
3 8 2 10
*/