【codevs3160】 LCS 【后缀自动机】
2024-09-21 18:49:17
题意
给出两个字符串,求它们的最长公共子串。
分析
后缀自动机的基础应用。
比如两个字符串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 ;
}
最新文章
- flex中image控件source属性改变的例子
- bnuoj 29373 Key Logger(模拟双向队列)
- Loadrunner通过sitescope监控mysql
- HDU 4274 Spy&#39;s Work (树 DFS)
- 细说javascript函数
- Speex manul中文版
- 进入MFC讲坛的前言(二)
- Linux Debugging(一): 使用反汇编理解C++程序函数调用栈
- 初识JAVA——流程控制之if语句
- spring定时器cron
- less,more,view一个文件时中文可以正常显示,可是VI却显示乱码呢?
- P1028 数的计算
- 虹软人脸识别 arcface2.0 安卓版本
- powerDesigner 把name项添加到注释(comment)
- Fortran 语法之流程控制
- 数组也继承了Object类
- September 20th 2017 Week 38th Wednesday
- busybox内置ftp服务器用法
- SurvivalShooter学习笔记(九.游戏暂停、结束)
- Please make sure the TESSDATA_PREFIX environment variable is set to your ";tessdata"; directory.