题意

给出两个字符串,求它们的最长公共子串。

分析

后缀自动机的基础应用。

比如两个字符串s1和s2,我们把s1建为SAM,然后根据s2跑,找出s2每个前缀的最长公共后缀。

我们可以理解为,当向尾部增加一个字母的时候,就按照匹配路径来走,当在SAM中找不到这样的字符串的时候,就要减少头部的字母,就顺着parent树往祖先结点走。

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <map> using namespace std;
const int maxn=1e5+;
char S[maxn],T[maxn];
int n,m;
struct state{
int len,link;
map<char,int>next;
}st[*maxn];
int last,cur,sz;
void init(){
last=cur=;
sz=;
st[].len=;
st[].link=-;
// st[0].next.clear();
}
void build_sam(char c){
cur=sz++;
st[cur].len=st[last].len+;
int p;
for(p=last;p!=-&&!st[p].next.count(c);p=st[p].link){
st[p].next[c]=cur;
}
if(p==-)
st[cur].link=;
else{
int q=st[p].next[c];
if(st[p].len+==st[q].len){
st[cur].link=q;
}else{
int clone=sz++;
st[clone].len=st[p].len+;
st[clone].next=st[q].next;
st[clone].link=st[q].link;
for(;p!=-&&st[p].next[c]==q;p=st[p].link){
st[p].next[c]=clone;
}
st[cur].link=st[q].link=clone;
}
}
last=cur;
} int main(){
scanf("%s%s",S,T);
n=strlen(S);
m=strlen(T);
init();
for(int i=;i<n;i++){
build_sam(S[i]);
}
int cur=;
int v=,len=,ans=;
for(int i=;i<m;i++){
if(st[v].next.count(T[i])){
v=st[v].next[T[i]];
len++;
}else{
while(v!=-&&!st[v].next.count(T[i])){
// printf("%d\n",v);
v=st[v].link;
len=st[v].len;
}
if(v==-)
v=len=;
else{
v=st[v].next[T[i]];
len++;
}
}
ans=max(ans,len);
}
printf("%d\n",ans); return ;
}

【codevs3160】 LCS 【后缀自动机】的更多相关文章

  1. POJ.2774.Long Long Message/SPOJ.1811.LCS(后缀自动机)

    题目链接 POJ2774 SPOJ1811 LCS - Longest Common Substring 确实比后缀数组快多了(废话→_→). \(Description\) 求两个字符串最长公共子串 ...

  2. SPOJ - LCS 后缀自动机入门

    LCS - Longest Common Substring A string is finite sequence of characters over a non-empty finite set ...

  3. SPOJ LCS 后缀自动机

    用后缀自动机求两个长串的最长公共子串,效果拔群.多样例的时候memset要去掉. 解题思路就是跟CLJ的一模一样啦. #pragma warning(disable:4996) #include< ...

  4. SPOJ LCS 后缀自动机找最大公共子串

    这里用第一个字符串构建完成后缀自动机以后 不断用第二个字符串从左往右沿着后缀自动机往前走,如能找到,那么当前匹配配数加1 如果找不到,那么就不断沿着后缀树不断往前找到所能匹配到当前字符的最大长度,然后 ...

  5. SPOJ 1811 LCS [后缀自动机]

    题意: 求两个串的最大连续子串 一个串建SAM,另一个串在上面跑 注意如果走了Suffix Link,sum需要更新为t[u].val+1 Suffix Link有点像失配吧,当前状态s走不了了就到S ...

  6. LCS2 - Longest Common Substring II(spoj1812)(sam(后缀自动机)+多串LCS)

    A string is finite sequence of characters over a non-empty finite set \(\sum\). In this problem, \(\ ...

  7. SPOJ 1811. Longest Common Substring (LCS,两个字符串的最长公共子串, 后缀自动机SAM)

    1811. Longest Common Substring Problem code: LCS A string is finite sequence of characters over a no ...

  8. SPOJ LCS Longest Common Substring(后缀自动机)题解

    题意: 求两个串的最大\(LCS\). 思路: 把第一个串建后缀自动机,第二个串跑后缀自动机,如果一个节点失配了,那么往父节点跑,期间更新答案即可. 代码: #include<set> # ...

  9. SPOJ1811 LCS - Longest Common Substring(后缀自动机)

    A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the s ...

随机推荐

  1. PHP----重置阿里云主机的密码

    登陆阿里云,找到你的服务器 点击更多,选择重置密码,根据提示就可以了 这个密码用于连接FTP工具和SSH工具

  2. 中兴G718C开发者模式开启

    系统设置--关于手机--版本号,连按七次,打开开发者选项 请进入设置——连接到PC——默认连接类型——安装驱动,选择即可.然后将手机和电脑连接,打开“我的电脑”或“计算机”会弹出可移动盘符“USB D ...

  3. filter防盗链

    1这次练习中一直受到相对路径的干扰,现在澄清一点 forward中不是不需要包含根目录的  比如 http://localhost:8080/filter/upload/images/no.jpg 你 ...

  4. 什么是Spark(三)数据的加载和保存

    Spark内置了一些常见的文件格式的处理,包括text/json,csv,sequence等:Spark对于文件处理保持了开放性,还提供了可以通过InputFormat,OutputFormat来进行 ...

  5. Android的AsyncQueryHandler详解

    摘抄别人的博客,看一下,里面有AsyncQueryHandler的详细介绍.http://blog.csdn.net/yuzhiboyi/article/details/8093408 自从frame ...

  6. java代码FileInputStream的复制粘贴练习

    所有的输入输出流都是对于程序来说的,这个图是实现文件内容的复制粘贴功能的e 首先把文件读到哦程序里,然后把程序读出到文件l package com.a.b; //这个复制和粘贴-----------首 ...

  7. ZOJ 3609 Modular Inverse(拓展欧几里得求最小逆元)

    Modular Inverse Time Limit: 2 Seconds      Memory Limit: 65536 KB The modular modular multiplicative ...

  8. JVM内存管理和问题简要分析学习

      Java中我们基本上不会显式地调用分配内存的函数,分配内存和回收内存都由JVM自动完成了.   所谓物理内存就是我们通常说的RAM(随机存储器),计算机中还有一个存储单元叫做寄存器,用于存储计算单 ...

  9. UGUI 旋转时钟功能

    两种模式: 1.Screen Space-Overlay public void OnDrag(PointerEventData eventData) { Vector2 targetDir = ev ...

  10. 运维平台cmdb开发-day2

    一 发送数据到api(Django的URL) 发送请求携带参数 requests.get(url='http://127.0.0.1:8000/api/asset/?k1=123') # <Qu ...