题意
给出一些字符串,有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]);
}
}

本文介绍了一种利用字典树高效求解多个字符串间最长公共前缀(LCP)问题的方法,通过增量式构建字典树并计算每一步新增字符串与已存字符串的最大LCP,实现了快速响应查询需求。
593

被折叠的 条评论
为什么被折叠?



