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 记录当前的最长公共 ...
随机推荐
- Java 内存查看与分析
1:gc日志输出 在jvm启动参数中加入 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimestamps -XX:+PrintGCApplication ...
- ARC072/ABC059
AtCoder Regular Contest 072 / Beginner Contest 059 Announcement <br > 猛然发现今天有一场AC.....然后..显示手残 ...
- P1136 超车 归并排序 求逆序对个数
这道题从看到它开始到做出来,已经过了快两周[因为第一次思路完全跑偏写的是暴力模拟想水过]: 题意是这样的: jzabc除了对多米诺骨牌感兴趣外,对赛车也很感兴趣.上个周末他观看了一场赛车比赛.他总是 ...
- 四个很好的开源app项目
Open Source and the iOS App Store Today, we are open-sourcing 4 iOS apps: ThatInbox, an email client ...
- 几点iOS开发技巧
转自I'm Allen的博客 原文:iOS Programming Architecture and Design Guidelines 原文来自破船的分享 原文作者是开发界中知晓度相当高 ...
- ubuntu安装常用软件
安装unzip sudo apt-get install unzip
- 配置mysql主从服务器
参考:https://www.linuxidc.com/Linux/2016-09/135633.htm 一.Master主服务器配置(192.168.1.3) 1.编辑my.cnf(命令查找文件位置 ...
- class文件结构浅析(2)
欢迎转载,转载需声明出处 ------------------ 请先看上一篇:Class类文件结构浅析 上一篇讲的都是理论.以下我们亲自实践一下. 首先编写一个简单的java类: public cla ...
- 苦逼IT才能看懂的笑话
这是苦逼IT才能看懂的笑话1.栈和队列的区别是啥? 吃多了拉就是队列:吃多了吐就是栈 2.世界上最遥远的距离不是生与死,而是你亲手制造的BUG就在你眼前,你却怎么都找不到她... 3.<c++程 ...
- MySQL的timeout那点事
http://www.mysqlops.com/2011/11/24/mysql_timeout.html