题意
给出一些字符串,有q次询问,问前k个字符串中两两之间的最大的LCP(最长公共前缀)。
思路
因为是前k个,我们就可以用一个数组来记录。把每次读入的字符串存进字典树里,在放进字典树的过程中我们可以很容易地计算出它和之前的字符串的LCP,然后和前面的比较就好了。
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,q,tot=1,trie[1000001][26],a,lcp[100001],x,f,tj,l;//trie[i][j]表示节点i的j字符指向的节点
char s[1000001];
int insert()
{
scanf("%s",s+1);
int x=1,f=1,tj=0,l=strlen(s+1);//这里我没有设l的话好像会超时
for (int i=1;i<=l;i++)
{
if (!trie[x][s[i]-'a']) {f=0;trie[x][s[i]-'a']=++tot;}//之前没有插入过我们就新开一个点,并且更新f
x=trie[x][s[i]-'a'];//跳
tj+=f;//如果当前字符串已经和之前的没有匹配了那么f会改成0,这里就没有累加LCP了
}
return tj;
}
int main()
{
scanf("%d%d",&n,&q);
for (int i=1;i<=n;i++)
lcp[i]=max(insert(),lcp[i-1]);
while (q--)
{
scanf("%d",&a);
printf("%d\n",lcp[a]);
}
}