SPOJ1811 LCS SAM
后缀自动机简单题。
其主要思路是,先对第一个字符串建立后缀自动机,把第二个串放在上面匹配,
若当前状态s有字符x的转移,直接转移len=step+1。
若当前状态s没有向字符x的转移,退回pres检查是否有转移,
若没有,则继续退回,否则转移到节点y,len=stepy+1。
以上思路主要利用的是关于pre节点的性质,由于pre节点的right集合是其子节点的right集合的并集,且max(pre)=min(s)-1.
所以从pre节点往上跳的时候,就能找到最长的后缀相同的部分的节点。(不知道这么说对不对)。
与KMP算法的很像。
可以参考这篇博客
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<iomanip>
#include<set>
#include<map>
#include<queue>
using namespace std;
#define mem1(i,j) memset(i,j,sizeof(i))
#define mem2(i,j) memcpy(i,j,sizeof(i))
#define LL long long
#define up(i,j,n) for(int i=(j);i<=(n);i++)
#define FILE "dealing"
#define poi vec
#define eps 1e-10
#define db double
const int maxn=,inf=,mod=;
int read(){
int x=,f=,ch=getchar();
while(x<''||x>''){if(ch=='-')f=-;ch=getchar();}
while(x<=''&&x>=''){x=(x<<)+(x<<)+ch-'',ch=getchar();}
return f*x;
}
bool cmax(int& a,int b){return a<b?a=b,true:false;}
namespace sam{
const int maxn=;
int pre[maxn],c[maxn][],len[maxn],now,cnt,np,p,q,nq,Len;
void clear(){mem1(c,);mem1(len,);mem1(pre,);cnt=,now=;}
void expend(int x){
np=++cnt;len[np]=len[now]+;p=now;now=np;
while(p&&!c[p][x])c[p][x]=np,p=pre[p];
if(!p)pre[np]=;
else {
q=c[p][x];
if(len[q]==len[p]+)pre[np]=q;
else {
len[nq=++cnt]=len[p]+;
pre[nq]=pre[q];
pre[q]=pre[np]=nq;
mem2(c[nq],c[q]);
while(p&&c[p][x]==q)c[p][x]=nq,p=pre[p];
}
}
}
int walk(int x){
while(!c[now][x]&&pre[now])now=pre[now],Len=len[now];
if(!c[now][x])return ;
now=c[now][x];Len++;return Len;
}
void build(char* s){
int n=strlen(s+);
up(i,,n)expend(s[i]-'a');
}
};
char s[maxn];
int main(){
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
sam::clear();
scanf("%s",s+);
sam::build(s);
scanf("%s",s+);
int n=strlen(s+);
int ans=;sam::now=;sam::Len=;
up(i,,n)cmax(ans,sam::walk(s[i]-'a'));
cout<<ans<<endl;
return ;
}
SPOJ1811 LCS SAM的更多相关文章
- spoj1811 LCS - Longest Common Substring
地址:http://www.spoj.com/problems/LCS/ 题面: LCS - Longest Common Substring no tags A string is finite ...
- SPOJ1811 LCS - Longest Common Substring(后缀自动机)
A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the s ...
- SAM初探
SAM,即Suffix Automaton,后缀自动机. 关于字符串有很多玩法,有很多算法都是围绕字符串展开的.为什么?我的理解是:相较于数字组成的序列,字母组成的序列中每个单位上元素的个数是有限的. ...
- POJ.2774.Long Long Message/SPOJ.1811.LCS(后缀自动机)
题目链接 POJ2774 SPOJ1811 LCS - Longest Common Substring 确实比后缀数组快多了(废话→_→). \(Description\) 求两个字符串最长公共子串 ...
- 后缀自动机(SAM) 学习笔记
最近学了SAM已经SAM的比较简单的应用,SAM确实不好理解呀,记录一下. 这里提一下后缀自动机比较重要的性质: 1,SAM的点数和边数都是O(n)级别的,但是空间开两倍. 2,SAM每个结点代表一个 ...
- POJ.2774.Long Long Message/SPOJ.1811.LCS(后缀数组 倍增)
题目链接 POJ2774 SPOJ1811 LCS - Longest Common Substring 比后缀自动机慢好多(废话→_→). \(Description\) 求两个字符串最长公共子串 ...
- BZOJ 4698: Sdoi2008 Sandy的卡片 [后缀自动机]
4698: Sdoi2008 Sandy的卡片 题意:差分后就是多个串LCS SAM+map大法好 模板打错 智力-2 #include <iostream> #include <c ...
- LCS - Longest Common Substring(spoj1811) (sam(后缀自动机)+LCS)
A string is finite sequence of characters over a non-empty finite set \(\sum\). In this problem, \(\ ...
- 【spoj1811 & spoj1812 - LCS1 & LCS2】sam
spoj1811 给两个长度小于100000的字符串 A 和 B,求出他们的最长公共连续子串. 先将串 A 构造为 SAM ,然后用 B 按如下规则去跑自动机.用一个变量 lcs 记录当前的最长公共 ...
随机推荐
- Codeforces 536C Tavas and Pashmaks(凸壳)
题目链接 Tavas and Pashmaks 题目大意:n个人比赛,游泳和赛跑,游泳距离S,赛跑R.每个人对应两个速度(陆地和水上的),如果存在S,R,使得第i个人胜利,那么输出i 题目要求输出所有 ...
- char 转string
c++: string.c_str() ---------> c: char c; string str;stringstream stream;stream << ...
- spring mvc利用MultipartResolver解析Multipart/form-data进行文件上传
之前的表单数据都是文本数据,现记录:利用MultipartResolver进行文件上传. ①首先,需引入commons-fileUpload和commons-io jar包,pom.xml文件的坐标: ...
- Java-线程池总结
线程池的优点: 重用线程,减少线程创建和销毁的性能开销. 管理线程,并提供定时执行以及指定间隔循环执行等功能. Android中的线程来源于Java中的Executor,实现类是ThreadPoolE ...
- cookie读取设置name
cookie就是k-v形式,可以理解为一个hashmap cookie就是k-v形式,可以理解为一个hashmap cookie就是k-v形式,可以理解为一个hashmap 建立一个无生命周期的coo ...
- zip 压缩文件夹
import java.io.*; import java.util.zip.*; /** * @author Dana·Li * <p> * 程序实现了ZIP压缩[compression ...
- 使用cacheBuilder实现函数防抖
在接口中出现的相同请求重复且连续发送的情况导致一些业务BUG,需要在接口上实现防抖 使用google的cacheBuilder import com.google.common.cache.Cache ...
- PS 如何制作眼泪效果
1.用钢笔工具勾出眼泪的路径然后按Ctrl + Enter转为选区 2.按Ctrl + J 把选区复制出来,执行滤镜 > 扭曲 > 球面化 同样的方法制作流出的眼泪,然后添加图层样式选择投 ...
- ajax加载时的进度条
运行效果如下图,pc和移动都可以展示,调用方法很简单,开始调用:loading.baosight.showPageLoadingMsg(false),false代表不现实加载说明,true展示加载说明 ...
- awk中的NR FNR
shell编程中,awk简直就是一把利器,你能够把它看成shell的一部分,也能够看成一种单独的语言,功能十分强大.今天先来说一说NR与FNR 先准备两个文件: 1.txt,内容为: user pas ...