HDU 1403 Longest Common Substring(后缀数组,最长公共子串)
参考了 罗穗骞的论文《后缀数组——处理字符串的有力工具》
题意:求两个序列的最长公共子串
思路:后缀数组经典题目之一(模版题)
//后缀数组sa:将s的n个后缀从小到大排序后将 排序后的后缀的开头位置 顺次放入sa中,则sa[i]储存的是排第i大的后缀的开头位置。简单的记忆就是“排第几的是谁”。
//名次数组rank:rank[i]保存的是suffix(i){后缀}在所有后缀中从小到大排列的名次。则 若 sa[i]=j,则 rank[j]=i。简单的记忆就是“你排第几”。
//对于 后缀数组sa 与 名次数组rank ,有rank[ sa[i] ]=i (这是很重要的一点,通过sa与rank的关系可以求出后缀数组)
//height 数组: 定义height[i]=suffix(sa[i-1]) 和 suffix(sa[i]) 的最长公共前缀,也就是排名相邻的两个后缀的最长公共前缀。 #include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std; #define maxn 200010
int wa[maxn],wb[maxn],wv[maxn],ws[maxn];
int cmp(int *r,int a,int b,int l)
{return r[a]==r[b]&&r[a+l]==r[b+l];}//yuan lai zhi qian ba zhe li de l cuo dang cheng 1 le ...
void da(int *r,int *sa,int n,int m)
{
int i,j,p,*x=wa,*y=wb,*t;
for(i=;i<m;i++)ws[i]=;
for(i=;i<n;i++)ws[x[i]=r[i]]++;
for(i=;i<m;i++)ws[i]+=ws[i-];
for(i=n-;i>=;i--)sa[--ws[x[i]]]=i;
for(j=,p=;p<n;j*=,m=p)
{
for(p=,i=n-j;i<n;i++)y[p++]=i;
for(i=;i<n;i++)if(sa[i]>=j) y[p++]=sa[i]-j;
for(i=;i<n;i++)wv[i]=x[y[i]];
for(i=;i<m;i++)ws[i]=;
for(i=;i<n;i++)ws[wv[i]]++;
for(i=;i<m;i++)ws[i]+=ws[i-];
for(i=n-;i>=;i--)sa[--ws[wv[i]]]=y[i];
for(t=x,x=y,y=t,p=,x[sa[]]=,i=;i<n;i++)
x[sa[i]]=cmp(y,sa[i-],sa[i],j)? (p-):p++;
}
}
int rankk[maxn],height[maxn];
void calheight(int *r,int *sa,int n)
{
int i,j,k=;
for(i=;i<=n;i++)rankk[sa[i]]=i;
for(i=;i<n;height[rankk[i++]]=k)
for(k? k--:,j=sa[rankk[i]-];r[i+k]==r[j+k];k++);
}
int RMQ[maxn];
int mm[maxn];
int best[][maxn];
void initRMQ(int n)
{
int i,j,a,b;
for(mm[]=-,i=;i<=n;i++)
mm[i]=((i&(i-))==) ? mm[i-]+:mm[i-];
for(i=;i<=n;i++)best[][i]=i;
for(i=;i<=mm[n];i++)
for(j=;j<=n+-(<<i);j++)
{
a=best[i-][j];
b=best[i-][j+(<<(i-))];
if(RMQ[a]<RMQ[b])best[i][j]=a;
else best[i][j]=b;
}
}
int askRMQ(int a,int b)
{
int t;
t=mm[b-a+];b-=(<<t)-;
a=best[t][a];b=best[t][b];
return RMQ[a]<RMQ[b]? a:b;
}
int lcp(int a,int b)
{
int t;
a=rankk[a]; b=rankk[b];
if(a>b) {t=a;a=b;b=t;}
return (height[askRMQ(a+,b)]);
} char s[maxn];
int r[maxn],sa[maxn];
int main()
{
while(scanf("%s",s)!=EOF)
{
int len1=strlen(s);
s[len1]='';//yin wei bu ce ng chu xian ,suo yi bu yong dan xin ying xiang jie guo
scanf("%s",s+len1+);
int len2=strlen(s); for(int i=;i<len2;i++)r[i]=s[i];//r[i]biao shi pai de shi di ji
r[len2]=;//ji shu pai xu shi de xu yao ,zui hou yi ge jia she wei zui xiao da(r,sa,len2+,);
calheight(r,sa,len2);
int ans=;
//bian li height shu zu, cong di 2 ge kai shi (xia biao shi cong 1 kai shi de )
for(int i=;i<=len2;i++)
{
if(height[i]>ans)
{
if((len1<sa[i]&&len1>sa[i-])||(len1>sa[i]&&len1<sa[i-]))
ans=height[i];
}
}
printf("%d\n",ans);
}
return ;
}
HDU 1403 Longest Common Substring(后缀数组,最长公共子串)的更多相关文章
- hdu 1403 Longest Common Substring 后缀数组 模板题
题目链接 题意 问两个字符串的最长公共子串. 思路 加一个特殊字符然后拼接起来,求得后缀数组与\(height\)数组.扫描一遍即得答案,注意判断起始点是否分别在两个串内. Code #include ...
- [SPOJ1811]Longest Common Substring 后缀自动机 最长公共子串
题目链接:http://www.spoj.com/problems/LCS/ 题意如题目,求两个串的最大公共子串LCS. 首先对其中一个字符串A建立SAM,然后用另一个字符串B在上面跑. 用一个变量L ...
- hdu 1403 Longest Common Substring(最长公共子字符串)(后缀数组)
http://acm.hdu.edu.cn/showproblem.php?pid=1403 Longest Common Substring Time Limit: 8000/4000 MS (Ja ...
- HDU 1403 Longest Common Substring(后缀自动机——附讲解 or 后缀数组)
Description Given two strings, you have to tell the length of the Longest Common Substring of them. ...
- HDU - 1403 - Longest Common Substring
先上题目: Longest Common Substring Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/32768 K ...
- HDU 1403 Longest Common Substring(最长公共子串)
http://acm.hdu.edu.cn/showproblem.php?pid=1403 题意:给出两个字符串,求最长公共子串的长度. 思路: 刚开始学后缀数组,确实感觉很难,但是这东西很强大,所 ...
- POJ 2774 Long Long Message&&HDU 1403 Longest Common Substring&&COJ 1203
后缀数组的买1送2题... HDU的那题数据实在是太水了,后来才发现在COJ和POJ上都是WA..原因在一点:在建立sa数组的时候里面的n应该是字符串长度+1....不懂可以去看罗大神的论文... 就 ...
- POJ 2217 (后缀数组+最长公共子串)
题目链接: http://poj.org/problem?id=2217 题目大意: 求两个串的最长公共子串,注意子串是连续的,而子序列可以不连续. 解题思路: 后缀数组解法是这类问题的模板解法. 对 ...
- POJ-2774-Long Long Message(后缀数组-最长公共子串)
题意: 给定两个字符串 A 和 B,求最长公共子串. 分析: 字符串的任何一个子串都是这个字符串的某个后缀的前缀. 求 A 和 B 的最长公共子串等价于求 A 的后缀和 B 的后缀的最长公共前缀的最大 ...
随机推荐
- [css filter]filter在界面实现滤镜效果
最近逛当当,发现当当尾品会的首页推荐最底端的商品链接是灰色的图片,然后鼠标hover之后就会变成正常的彩色 肯定不是通过img来改变的,然后直接看了一下源码,其实是用的filter属性 _(:з」∠) ...
- flask程序部署在openshift上的一些注意事项
https://www.openshift.com/blogs/how-to-install-and-configure-a-python-flask-dev-environment-deploy-t ...
- JavaWeb之 JSP:内置对象,EL表达式,JSP标签基础
JSP的内置对象 什么是JSP的内置对象呢? 在JSP页面进行编程的时候,如果我们要使用一些对象,如:HttpSession,ServletConfig,ServletContext这些对象,如果每次 ...
- SQL语句中各种数据类型转换方法总结
1.Access 每个函数都可以强制将一个表达式转换成某种特定数据类型. 语法 CBool(expression) CByte(expression) CCur(expression) CDate(e ...
- oracle expdp impdp
一.不管导入还有导出都要先创建目录 1.创建目录 create directory my_dir as 'd:\yth';--生成目录(必须在指定位置先创建文件夹,名称最好与用户名一致) yth:是目 ...
- DeviceOne开发HelloWord
http://www.cnblogs.com/wjiaonianhua/p/5278061.html http://www.jb51.net/article/75693.htm 2015 年 9 月 ...
- orcle 查询数据集对变量赋值函数
create or replace function test(Name in varchar2 ) return varchar2 is V_CONTAINERDESC CHAR ); BEGIN ...
- ASP.NET2.0中对TextBox的Enable和ReadOnly属性的限制
在以前的ASP.NET 1.x版本中,设置为ReadOnly的TextBox控件在客户端更改了值后,在服务器端仍然可以得到修改后的值,但在ASP.NET 2.0中,这种做法已经限制.这是为了提高应用程 ...
- iOS进阶学习-CoreData
一.CoreData数据库框架的优势 1.CoreData数据持久化框架是Cocoa API的一部分,首次在iOS5版本的系统中出现,它允许按照实体-属性-值模型组织数据,并以XML.二进制文件或者S ...
- IOS应用程序升级
IOS应用程序升级流程介绍:IOS手机端应用程序需要升级时,打开服务器端html文件(本文为ucab.html文件)->点击在线安装->打开plist文件(本文中为ucab.plist文件 ...