当前位置: 首页 > news >正文

SPOJ 1812 Longest Common Substring II

http://www.spoj.com/problems/LCS2/

 

题意:

求10个串的LCS

 

1、用第一个串建立后缀自动机

2、len[s] 表示状态s 所能代表的字符串的最大长度

      mx[s] 表示状态s 在 当前匹配的串的最长匹配后缀长度

      ans[s] 表示状态s 在所有串的最长匹配后缀长度

3、用第2——第10个串在后缀自动机上跑,每次mx[s]=max(mx[s],当前匹配长度)

      每一个串跑完之后,更新 ans[s]=min(ans[s],mx[s])

4、每次匹配完一个字符串的时候,要 从后缀自动机 parent 树 上的叶子节点 向根更新,

   因为后缀自动机的parent树上,min[s]=max(fa[s])+1,所以子节点能匹配的长度 比 父节点的max要长。父节点是子节点的后缀,父节点可以匹配子节点的后max(fa[s])位,但是在那串在后缀自动机上跑的时候,不能保证经过 s 的 时候 也经过了s到根的链。所以只要子节点s 有匹配长度,父节点的mx[fa[s]]即可修改为len[fa[s]]即max(fa[s])

 

#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

#define N 100002

char s[N];

int tot=1,len[N<<1],ch[N<<1][26],fa[N<<1];
int last=1,p,q,np,nq;

int c[N],sa[N<<1];

int mx[N<<1],ans[N<<1];

void extend(int c)
{
    len[np=++tot]=len[last]+1;
    ans[tot]=len[tot];
    for(p=last;p && !ch[p][c];p=fa[p]) ch[p][c]=np;
    if(!p) fa[np]=1;
    else
    {
        q=ch[p][c];
        if(len[q]==len[p]+1) fa[np]=q;
        else
        {
            nq=++tot;
            memcpy(ch[nq],ch[q],sizeof(ch[q]));
            fa[nq]=fa[q];
            fa[q]=fa[np]=nq;
            ans[nq]=len[nq]=len[p]+1;
            for(;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
        }
    }
    last=np;
}

void build()
{
    scanf("%s",s+1);
    int L=strlen(s+1);
    for(int i=1;i<=L;++i) extend(s[i]-'a');
    for(int i=1;i<=tot;++i) c[len[i]]++;
    for(int i=1;i<=L;++i) c[i]+=c[i-1];
    for(int i=tot;i;--i) sa[c[len[i]]--]=i;
}

void solve()
{
    int L,c,now,now_len;
    int x;
    while(scanf("%s",s+1)!=EOF)
    {
        L=strlen(s+1);
        now=1;
        now_len=0;
        for(int i=1;i<=L;++i)
        {
            c=s[i]-'a';
            while(now && !ch[now][c]) 
            {
                now=fa[now];
                now_len=len[now];
            }
            if(!now)
            {
                now_len=0;
                now=1;
            }
            else if(ch[now][c])
            {
                now_len++;
                now=ch[now][c];
            }
            mx[now]=max(mx[now],now_len);
        }
        for(int i=tot;i;--i)
        {
            x=sa[i];
            ans[x]=min(ans[x],mx[x]);
            if(fa[x] && mx[x]) mx[fa[x]]=len[fa[x]];
            mx[x]=0;
        }
    }
    int out=0;
    for(int i=1;i<=tot;++i) out=max(out,ans[i]);
    printf("%d",out);
}

int main()
{
    build();
    solve();
    return 0;
}

 

转载于:https://www.cnblogs.com/TheRoadToTheGold/p/8531052.html

相关文章:

  • 北大ACM题库习题分类与简介(转载)
  • js整理
  • docker-dockerfile使用
  • ios按钮点击后翻转效果
  • 为什么说IBM公司未来云计算中成功的关键是开源
  • 序列化 serialVersionUID
  • windows下的套接字IO模型
  • 第一周考试总结
  • ExtJs中组件最好少使用ID属性(推荐更多使用Name属性)
  • 读书笔记-《JavaScript高级程序设计(第3版)》
  • ASP.NET MVC Model验证(一)
  • OpenCV+python轮廓
  • Objective-C语法之NSSet和NSMutableSet
  • 孤独与寂寞
  • 人工智能火了,为啥医疗成为最先受益者?
  • Apache的80端口被占用以及访问时报错403
  • CAP理论的例子讲解
  • CSS相对定位
  • JS题目及答案整理
  • Laravel 菜鸟晋级之路
  • Python打包系统简单入门
  • React的组件模式
  • spring security oauth2 password授权模式
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • - 概述 - 《设计模式(极简c++版)》
  • 简单数学运算程序(不定期更新)
  • 解决jsp引用其他项目时出现的 cannot be resolved to a type错误
  • 前端自动化解决方案
  • 实习面试笔记
  • 实现菜单下拉伸展折叠效果demo
  • 试着探索高并发下的系统架构面貌
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 微信小程序开发问题汇总
  • 微信小程序设置上一页数据
  • 我有几个粽子,和一个故事
  • 项目管理碎碎念系列之一:干系人管理
  • 用Canvas画一棵二叉树
  • #Z0458. 树的中心2
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (11)MATLAB PCA+SVM 人脸识别
  • (173)FPGA约束:单周期时序分析或默认时序分析
  • (33)STM32——485实验笔记
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (二)hibernate配置管理
  • (附源码)ssm高校升本考试管理系统 毕业设计 201631
  • (简单有案例)前端实现主题切换、动态换肤的两种简单方式
  • (强烈推荐)移动端音视频从零到上手(下)
  • (推荐)叮当——中文语音对话机器人
  • ***linux下安装xampp,XAMPP目录结构(阿里云安装xampp)
  • ***php进行支付宝开发中return_url和notify_url的区别分析
  • .net core MVC 通过 Filters 过滤器拦截请求及响应内容
  • .net连接oracle数据库
  • .NET委托:一个关于C#的睡前故事
  • .net专家(高海东的专栏)