spoj1811 Longest Common Substring(LCS),后缀自动机
来源:互联网 发布:openstack linux 编辑:程序博客网 时间:2024/05/22 17:24
spoj1811LCS
指向一个状态,这个状态的接受串s[x..x+i]是与当前状态的接受串后缀s[j-i..j]匹配是最长的一个。
这里是不是发现了一个和KMP很像的性质?
KMP在失配时通过next数组回退,那么这个回退到的位置i是s[0..i]与当前串的后缀s[j-i..j]匹配最长的一个。
所以。
利用后缀自动机可以求解一个串的子串(s[x..])与另一个串的子串的最长匹配长度。
问两个字符串最长公共子串。
做法很简单。匹配成功,则tl++,失败,从父指针回退,tl=t[now].len。
指向一个状态,这个状态的接受串s[x..x+i]是与当前状态的接受串后缀s[j-i..j]匹配是最长的一个。
这里是不是发现了一个和KMP很像的性质?
KMP在失配时通过next数组回退,那么这个回退到的位置i是s[0..i]与当前串的后缀s[j-i..j]匹配最长的一个。
所以。
利用后缀自动机可以求解一个串的子串(s[x..])与另一个串的子串的最长匹配长度。
KMP可以求解一个串(s[0..])与另一个串的子串的最长匹配长度。
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define Maxn 250100int root,last;//samint tots;struct sam_node{ int fa,son[26]; int len; void init(int _len){len=_len;fa=-1;memset(son,-1,sizeof(son));}}t[Maxn*2];//length*2void sam_init(){ tots=0; root=last=0; t[tots].init(0);}void extend(char ch){ int w=ch-'a'; int p=last; int np=++tots;t[tots].init(t[p].len+1); int q,nq; while(p!=-1&&t[p].son[w]==-1){t[p].son[w]=np;p=t[p].fa;} if (p==-1) t[np].fa=root; else{ q=t[p].son[w]; if (t[p].len+1==t[q].len){t[np].fa=q;} else{ nq=++tots;t[nq].init(0); t[nq]=t[q]; t[nq].len=t[p].len+1; t[q].fa=nq;t[np].fa=nq; while(p!=-1&&t[p].son[w]==q){t[p].son[w]=nq;p=t[p].fa;} } } last=np;}char s[Maxn];char f[Maxn];int work(int l2){ int i,now=root,ind,tl=0; int ret=0; for(i=0;i<l2;++i){ ind=f[i]-'a'; while(now!=-1&&t[now].son[ind]==-1){ now=t[now].fa; if (now!=-1) tl=t[now].len; } if (now==-1) {now=root;tl=0;} else { now=t[now].son[ind]; tl++; ret=max(ret,tl); } } return ret;}int main(){ int l1,l2,i,ans; scanf("%s",s); scanf("%s",f); l1=strlen(s); l2=strlen(f); sam_init(); for(i=0;i<l1;++i) extend(s[i]); ans=work(l2); printf("%d\n",ans); return 0;}
0 0
- spoj1811 Longest Common Substring(LCS),后缀自动机
- [SPOJ1811]LCS - Longest Common Substring(后缀自动机)
- SPOJ1811 Longest Common Substring后缀自动机
- [SPOJ1811]Longest Common Substring-后缀自动机
- [SPOJ1811]LCS - Longest Common Substring
- SPOJ LCS Longest Common Substring 后缀自动机
- [SPOJ LCS]Longest Common Substring && 后缀自动机
- 【后缀自动机】[SPOJ LCS]Longest Common Substring
- spoj1811 Longest Common Substring(LCS)最长公共子串
- spoj 1811 LCS - Longest Common Substring (后缀自动机)
- 【后缀自动机】SPOJ(LCS)[Longest Common Substring]题解
- spoj1811 Longest Common Substring
- SPOJ1812:Longest Common Substring(后缀自动机)
- SPOJ 题目1811 LCS - Longest Common Substring(后缀自动机求最长公共子串)
- 【spoj1811】Longest Common Substring【SAM】
- LCS(longest common subsequence)与LCS(longest common substring)以及后缀数组
- 后缀数组 spoj LCS - Longest Common Substring
- SPOJ 1811. Longest Common Substring (LCS,两个字符串的最长公共子串, 后缀自动机SAM)
- 报数游戏
- 融云开发者沙龙(济南站)活动精彩回顾
- Android基础进阶(一)
- C/C++学习笔记28:类型转换
- C++派生继承访问权限
- spoj1811 Longest Common Substring(LCS),后缀自动机
- poj 3744 Scout YYF I(概率dp+矩阵快速幂)
- 挑战面试编程:字符串包含
- ZooKeeper Watches
- free(p)后指针问题
- OpenStack live-migration 流程及配置
- 小鑫的城堡
- Android硬件抽象层(HAL)概要介绍和学习计划
- 产生和等于100的5个随机数