SPOJ_LCS
经典题目,求两个串的最长公共子串。
是这样来做的。
以第一个串构造SAM,第二个串在自动机上跟新一遍就可以了。
更新的过程是这样的,假设当前到达的状态点为x(初始状态为0点),下一个字符是c,如果当前状态没有c这条边就一直沿着pre指针走,直到找到第一个有c这条边的状态或者确认全部都没有。
更新是这样的,用一个数字保存上一次状态的最大长度tmp,现在到达了一个新的状态了,显然这个状态一定保证在第二个串出现,因为我是从第二个串里面一个一个字符地添加进来的,那么只要保证满足第一个串(即模式串)就可以了。怎么保证呢?只要不大于tmp不大于该状态的step值就可以了。为什么?因为能到达当前状态的话说明是可以存在这个长度的。tmp与step比较并且去较小值。就完成了更新了。
嗯其实还听简单的。
代码君上了:
#include <iostream>
#include <cstdio>
#include <cstring>
#define maxn 600300
using namespace std; int next[maxn][26],pre[maxn],step[maxn];
int N=0,last=0,n,p,q,np,nq;
char s[maxn]; void insert(int x,int m)
{
p=last,np=++N;
for (int i=0; i<26; i++) next[N][i]=0; pre[N]=0; step[N]=0;
step[np]=m;
for (;p!=-1 && next[p][x]==0; p=pre[p]) next[p][x]=np;
last=np;
if (p==-1) return;
q=next[p][x];
if (step[q]==step[p]+1) { pre[np]=q; return; }
nq=++N;
for (int i=0; i<26; i++) next[N][i]=0; pre[N]=0; step[N]=0;
step[nq]=step[p]+1;
pre[nq]=pre[q];
for (int i=0; i<26; i++) next[nq][i]=next[q][i];//注意指针不能乱。。
pre[np]=pre[q]=nq;
for (;p!=-1 && next[p][x]==q; p=pre[p]) next[p][x]=nq;
} int dfs()
{
int ans=0,tmp=0;
for (int i=1,cur=0; s[i]; i++)
{
int k=s[i]-'a';
while (next[cur][k]==0 && cur!=0) cur=pre[cur];
if (step[cur]<tmp) tmp=step[cur];
cur=next[cur][k];
if (cur) tmp++;
ans=max(ans,tmp);
}
return ans;
} int main()
{
pre[0]=-1;
for (int i=0; i<26; i++) next[0][i]=0; step[0]=0;
scanf("%s",s+1);
for (int i=1; s[i]; i++) insert(s[i]-'a',i);
scanf("%s",s+1);
printf("%d\n",dfs());
return 0;
}
SPOJ_LCS的更多相关文章
- SPOJ 1811. Longest Common Substring (LCS,两个字符串的最长公共子串, 后缀自动机SAM)
1811. Longest Common Substring Problem code: LCS A string is finite sequence of characters over a no ...
随机推荐
- C++对运算符进行重载学习笔记
1. 一个类的成员函数是暗含着 this 指针的,eg; #include<iostream> using namespace std; class A{ public: A(){ x ...
- Float浮点数的使用和条件
在这里简单的说一下,我对浮点数的理解,可能说的比较浅,老师也没有说,只是略微的提了一下,完全是我自己个人的理解. 我觉得float浮点数的用法和int的用法有些雷同,浮点数用于计算小数点单位,我们先可 ...
- linux 开机报错,error grub_efi_find_mmap_size not find
开机报错,差点以为要重装系统了 搜到了官方的重建引导的教程 修复了错误 https://wiki.manjaro.org/index.php/Restore_the_GRUB_Bootloader#F ...
- 微服务构建: Spring Boot
在展开 Spring Cloud 的微服务架构部署之前, 我们先了解一下用于构建微服务的基础框架-Spring Boot. 由于 Spring Cloud 的构建基于 Spring Boot 实现, ...
- 【转】利用telnet来进行调试Skynet
https://blog.csdn.net/WhereIsHeroFrom/article/details/80674408
- SSH免密登录(并且免yes交互)
问题描述:主机A使用ssh协议远程主机B,默认会开启口令认证,即输入主机B对应用户的登录密码,并且第一次登录时,主机A需验证是否接受来自主机B的公钥,输入"yes/no"完成交互. ...
- 高可用OpenStack(Queen版)集群-15.Glance&Cinder集成Ceph
参考文档: Install-guide:https://docs.openstack.org/install-guide/ OpenStack High Availability Guide:http ...
- HDU 1556 Color the ball (一维树状数组,区间更新,单点查询)
中文题,题意就不说了 一开始接触树状数组时,只知道“单点更新,区间求和”的功能,没想到还有“区间更新,单点查询”的作用. 树状数组有两种用途(以一维树状数组举例): 1.单点更新,区间查询(即求和) ...
- Daily Scrumming* 2015.10.30(Day 11)
一.总体情况总结 今日项目总结: 1.前后端同一了API设计以及API权限认证.用户状态保存的开发方案 2.API以及后端模型已经开始开发,前端UEditor开始学习,本周任务有良好的起步 3.前后端 ...
- 20172325 2016-2017-2 《Java程序设计》第四周学习总结
20172325 2016-2017-2 <Java程序设计>第四周学习总结 教材学习内容总结 1.对类.对象.声明变量的定义和属性有了进一步的了解 2.学会如何编写一个类并运用到需要的程 ...