poj2217
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 1257 | Accepted: 515 |
Description
Input
Output
Sample Input
2
Tady nejsou zadni mimozemstani.
Lide tady take nejsou.
Ja do lesa nepojedu.
V sobotu pojedeme na vylet.
Sample Output
Nejdelsi spolecny retezec ma delku 7.
Nejdelsi spolecny retezec ma delku 5.
白书上的题目,也看了答案。刚开始做的时候先看看,以后再自己想把。
第一道高度数组。
白书上的思路:首先想一个简化的问题:如何求出一个字符串中出现过两次以上的子串的最大长度。我们可以发现这样的子串分别是两个后缀的前缀,并且这两个后缀在后缀数组中是相邻的,因为这两个后缀的前缀相同,那么他们的排名是由长度决定的,肯定就是相邻了。
但是两个字符串就不好搞了,这时我们可以转化一下:把两个字符串拼在一起,就是直接头接尾(白书上说中间要加一个字符,我没接也对了)然后求出lcp,这时只要计算lcp的最大值就是答案了。但是注意,因为一个字符串是被拼在后面的,那么
sa[i]和sa[i-1]必须一个<s.length(),一个>=s.length()(s:第一个字符串),才能满足条件,为什么呢,因为我们求的是这两个字符串中出现的子串,所以当然sa必须一前一后了
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 20010
int n,ans,k;
int sa[N],lcp[N],rank[N],temp[N];
string s,t,S;
bool cp(int i,int j)
{
if(rank[i]!=rank[j]) return rank[i]<rank[j];
int ri=i+k<=n?rank[i+k]:-;
int rj=j+k<=n?rank[j+k]:-;
return ri<rj;
}
void Sa(string s)
{
n=s.length()-;
for(int i=;i<=n;i++)
{
rank[i]=s[i]; sa[i]=i;
}
for(k=;k<=n;k*=)
{
sort(sa,sa+n+,cp);
temp[sa[]]=;
for(int i=;i<=n;i++)
{
temp[sa[i]]=temp[sa[i-]]+(cp(sa[i-],sa[i]));
}
for(int i=;i<=n;i++) rank[i]=temp[i];
}
}
void Lcp(string s)
{
n=s.length()-;
for(int i=;i<=n;i++) rank[sa[i]]=i;//位置为sa[i]rank为i
lcp[]=;
int h=;
for(int i=;i<=n;i++)
{
int j=sa[rank[i]-];//这个位置的rank为i,上一个地方的位置则为rank-1,sa存的是排名对应的位置
if(h>) h--;
while(s[i+h]==s[j+h]&&i+h<=n&&j+h<=n) h++;
lcp[rank[i]-]=h;
}
}
int main()
{
int T; scanf("%d",&T);
cin.ignore();
while(T--)
{
memset(sa,,sizeof(sa));
ans=;
getline(cin,s,'\n');
getline(cin,t,'\n');
S=s+t;
int ls=s.length();
Sa(S); Lcp(S);
// printf("\n-------------\n");
for(int i=;i<S.length();i++)
{
// printf("lcp=%d\n",lcp[i-1]);
if((sa[i]>=ls&&sa[i-]<ls)||(sa[i]<ls&&sa[i-]>=ls))
ans=max(ans,lcp[i-]);
}
printf("Nejdelsi spolecny retezec ma delku %d.\n",ans);
}
return ;
}
poj2217的更多相关文章
- POJ2217 Secretary 后缀数组&&高度数组
学后缀数组后的一道裸题.先来讲讲收获,作为字符串初学者,后缀数组也是刚刚在学,所幸的是有一篇好的论文<后缀数组--处理字符串的有力工具>by 罗穗骞,里面非常详尽地介绍了有关后缀数组的概念 ...
- POJ2217(最长公共子串)
Secretary Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 992 Accepted: 408 Descripti ...
- poj2217 Secretary 后缀数组
#include <iostream> #include <cstring> #include <string> #include <cstdio> u ...
随机推荐
- Django模型类Meta元数据详解
转自:https://my.oschina.net/liuyuantao/blog/751337 简介 使用内部的class Meta 定义模型的元数据,例如: from django.db impo ...
- R语言:常用统计检验
统计检验是将抽样结果和抽样分布相对照而作出判断的工作.主要分5个步骤: 建立假设 求抽样分布 选择显著性水平和否定域 计算检验统计量 判定 -- 百度百科 假设检验(hypothesis test)亦 ...
- 9.2.2 .net framework下的MVC 控件的封装(下)
控件封装的部分说明 可能有人觉得应该前后端分离,我也承认这是应该的方向,我们也在考虑使用ng2等简化前端.但是,我们封装控件还是因为如下原因综合考虑的: 我们这是个框架,上面支撑了许多个应用,包含几百 ...
- 仿QQ空间根据位置弹出PopupWindow显示更多操作效果
我们打开QQ空间的时候有个箭头按钮点击之后弹出PopupWindow会根据位置的变化显示在箭头的上方还是下方,比普通的PopupWindow弹在屏幕中间显示好看的多. 先看QQ空间效果图: ...
- JS实现文字截取(雾)
今天在跳板群那里看到一个神奇的样式,效果: 感觉十分神奇,因为一开始以为他是只有一个P元素包着文字然后最后一个自动截取文字,而且最后一行还可以提前截取???这怎么做到的,然后想了一下css怎么做,好像 ...
- SAP CRM 7.0中的BOL(Business Object Layer)
业务对象层(BOL)和通用交互层(GenIL)属于业务层. 业务对象层: 在CRM WebClient会话运行期间,业务对象层存储业务对象的数据以及它们属性和关系的定义. 通用交互层 通用交互层将 ...
- Linux 命令学习笔记
文件基本操作 ls ,rm , mv , ln ls ls [option] [files] 不带参数时,列出当前工作目录的内容 $ls 列出指定目录的内容 ls dir1 或个别文件 l ...
- Android中使用ViewPager实现屏幕页面切换和页面切换效果
之前关于如何实现屏幕页面切换,写过一篇博文<Android中使用ViewFlipper实现屏幕切换>,相比ViewFlipper,ViewPager更适用复杂的视图切换,而且Viewpag ...
- Looper.prepare()和Looper.loop()
什么时候需要 Looper Looper用于封装了android线程中的消息循环,默认情况下一个线程是不存在消息循环(message loop)的,需要调用Looper.prepare()来给线程创建 ...
- C#委托的介绍(delegate、Action、Func、predicate)
委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递.事件是一种特殊的委托. 1.委托的声明 (1). delegate delegate我们常用到的一种声明 Deleg ...