【GDKOI2013选拔】大LCP
题目
LCP就是传说中的最长公共前缀,至于为什么要加上一个大字,那是因为…你会知道的。
首先,求LCP就要有字符串。既然那么需要它们,那就给出n个字符串好了。
于是你需要回答询问大LCP,询问给出一个k,你需要求出前k个字符串中两两的LCP最大值是多少,这就是传说中的大LCP。
分析
考虑离线操作,
用\(ans_k\)表示前k个字符串中两两的LCP最大值
建一棵trie,
依次把输入的字符放入trie,
当做到i时,\(ans_i\)也可以顺便求出来。
#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const int maxlongint=2147483647;
using namespace std;
struct wordtree
{
int fz[27];
}tree[2000005];
char s[1000000];
int f[100003],n,m,tot,ans;
int main()
{
scanf("%d%d",&n,&m);
int i,j,k,l,x,y,mx;
tot=1;
for(i=1;i<=n;i++)
{
scanf("%s\n",s);
x=1;
mx=strlen(s);
for(j=0;j<=mx-1;j++)
{
if(tree[x].fz[s[j]-97]) x=tree[x].fz[s[j]-97];
else
break;
}
for(k=j;k<=mx-1;k++)
{
tree[x].fz[s[k]-97]=++tot;
x=tot;
}
mx=j;
f[i]=max(f[i-1],mx);
}
for(i=1;i<=m;i++)
{
scanf("%d",&k);
printf("%d\n",f[k]);
}
}