文章目录
- 题目描述
- 解析
- 代码
题目描述
解析
(没有做出来,这个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 16 4 10
3 5 2 7 1 9
3 8 2 10
*/