题意

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

分析

后缀自动机的基础应用。

比如两个字符串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. centos6.5 ifconfig没有ipv4地址

    进入/etc/sysconfig/network-scripts/目录中,可以看到ifcfg-eth0文件, vi ifcfg-eth0编辑文件, 将“ONBOOT=no” 选项改成“ONBOOT=y ...

  2. [LeetCode系列]最大容器问题

    给定n个数: a1, a2, ... , an. 代表着(i, ai)个点, 连接这些点与对应的(i, 0), 我们可以得到n条线. 请在这n条线中找出2条, 使得这两条线和x轴构成的容器能够容纳最多 ...

  3. 揭晓UX(用户体验)最大的秘密

    我是佩恩和特勒的粉丝已经多年了.我第一次在现实中看到他们是在上个月,被他们的表演完全迷住了. 我真的很喜欢佩恩和特勒,他们经常“回拉窗帘”,并揭示他们是怎么完成他们的魔法.其他魔术师营造神秘主义和虚假 ...

  4. linux下踢出已登录用户

    通过xshell登录到linux,看到如下所示,有3个用户,但是前面两个不知在哪登录的了,那就踢出吧. 先确认一下自己是哪个 顺便注意一下“whoami”和“who am i”的不同 然后踢出前面两个 ...

  5. CSS各浏览器HACK

    /*firefox*/@-moz-document url-prefix(){.mainNews div.l ul{padding-bottom:12px}} /*ie6*/{_padding:2px ...

  6. Android UI一些技巧

    (1)去掉EditText的背景颜色  android:background="@null" (2)ListView 修改某行的值,因为一些功能逻辑,需要修改ListView某行的 ...

  7. java代码--------构造方法的调用

    总结: package com.sads; //构造方法何时被调用, //构造方法里的内容先执行 public class Sdw { static { System.out.println(&quo ...

  8. NFV网络功能虚拟化 基本概念

    NFV基本概念 NFV则由运营商联盟提出,为了加速部署新的网络服务,运营商倾向于放弃笨重昂贵的专用网络设备,转而使用标准的IT虚拟化技术来拆分网络功能模块,如DNS.NAT.Firewall等.于是一 ...

  9. 028:基于mysqldump备份脚本

    MySQL Backup and Recovery 一 MySQL Backup 1.功能 mysqldump全量和增量备份,通过最近一次备份刷新产生binlog来定位执行增量. 脚本下载地址 git ...

  10. (转) C#中Timer使用及解决重入(多线程同时调用callback函数)问题

    原文链接: http://www.cnblogs.com/hdkn235/archive/2014/12/27/4187925.html