【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]);
    }
}

转载于:https://www.cnblogs.com/chen1352/p/9045319.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值