POJ 1743 [USACO5.1] Musical Theme (后缀数组+二分)
题目大意:给你一个序列,求其中最长的一对相似等长子串
一对合法的相似子串被定义为:
1.任意一个子串长度都大于等于5
2.不能有重叠部分
3.其中一个子串可以在全部+/-某个值后和另一个串完全相同
还是老套路了,其实只要求出每一项和前一项的差值序列,这样第三个问题可以被转化为求最长不重叠的相同子串,最后把答案+1就行了
这道题竟然还是LTC大佬的男人八题!正解是后缀数组+二分,但据说可以n^2骗分过
思路是先求出height数组,对于排序后的字符串集合有一个神奇的性质,如果有某连续的几个字符串height>=x,那么这几个字符串的公共前缀长度>=x,可以用Trie树的思想很容易地证明
那现在就要解决第二个问题,不能有重叠部分
直接求解不容易,所以我们二分答案去做,每次二分出一个答案x,然后去height数组里找,把连续的几个height>=x字符串想象成一块,那么如果这个块合法,这一块内一定存在两个字符串的sa[i]-sa[j]>=x,也就是在这一块内找出sa[i]的最大最小值就行啦
复杂度O(nlogn)
傻了吧唧的把后缀数组敲错了,调了半个小时
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 20010
#define inf 0x3f3f3f3f
#define maxn 100
using namespace std; int n,len;
int a[N],b[N],tr[N],rk[N],sa[N],hs[N],h[N];
int gint()
{
int rett=,fh=;char c=getchar();
while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
while(c>=''&&c<=''){rett=(rett<<)+(rett<<)+c-'';c=getchar();}
return rett*fh;
}
void clr()
{
memset(a,,sizeof(a));memset(tr,,sizeof(tr));
memset(b,,sizeof(b));memset(rk,,sizeof(rk));
memset(h,,sizeof(h));memset(sa,,sizeof(sa));
memset(hs,,sizeof(hs));
}
bool check(int k,int x,int y){
if(x+k>len||y+k>len) return ;
else return (rk[x]==rk[y]&&rk[x+k]==rk[y+k])?:;
}
void get_sa()
{
int cnt=,i=;
for(i=;i<=n;i++) hs[b[i]]++;
for(i=;i<=*maxn;i++) if(hs[i]) tr[i]=++cnt;
for(i=;i<=*maxn;i++) hs[i]+=hs[i-];
for(i=;i<=n;i++) rk[i]=tr[b[i]],sa[hs[b[i]]--]=i;
for(int k=;cnt<len;k<<=)
{
for(i=;i<=cnt;i++) hs[i]=;
for(i=;i<=len;i++) hs[rk[i]]++;
for(i=;i<=cnt;i++) hs[i]+=hs[i-];
for(i=len;i>=;i--) if(sa[i]>k) tr[sa[i]-k]=hs[rk[sa[i]-k]]--;
for(i=;i<=k;i++) tr[len-i+]=hs[rk[len-i+]]--;
for(i=;i<=len;i++) sa[tr[i]]=i;
for(i=,cnt=;i<=len;i++) tr[sa[i]]=check(k,sa[i],sa[i-])?cnt:++cnt;
for(i=;i<=len;i++) rk[i]=tr[i];
}
}
void get_height()
{
for(int i=;i<=len;i++){
if(rk[i]==) continue;
for(int j=max(,h[rk[i-]]-);j;j++)
if(b[i+j-]==b[sa[rk[i]-]+j-]) h[rk[i]]=j;
else break;
}
}
bool check(int ans)
{
int i=,j=;
for(i=;i<=len;)
{
if(h[i]<ans) {i++;continue;}
int mi=sa[i-],ma=sa[i-];
for(;h[i]>=ans&&i<=len;i++)
{
mi=min(mi,sa[i]);
ma=max(ma,sa[i]);
if(ma-mi>ans) return ;
}
}return ;
} int main()
{
while(scanf("%d",&n)&&n!=)
{
len=n;
clr();
for(int i=;i<=n;i++)
a[i]=gint(),b[i]=a[i]-a[i-]+maxn;
get_sa();
get_height();
int l=,r=n,ans=;
while(l<=r){
int mid=(l+r)>>;
if(check(mid)) ans=mid,l=mid+;
else r=mid-;
}
if(ans<) printf("0\n");
else printf("%d\n",ans+);
}
return ;
}
POJ 1743 [USACO5.1] Musical Theme (后缀数组+二分)的更多相关文章
- Poj 1743 Musical Theme(后缀数组+二分答案)
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 28435 Accepted: 9604 Descri ...
- Poj 1743 Musical Theme (后缀数组+二分)
题目链接: Poj 1743 Musical Theme 题目描述: 给出一串数字(数字区间在[1,88]),要在这串数字中找出一个主题,满足: 1:主题长度大于等于5. 2:主题在文本串中重复出现 ...
- POJ1743 Musical Theme(后缀数组 二分)
Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 33462 Accepted: 11124 Description A m ...
- POJ 1743 Musical Theme ——后缀数组
[题目分析] 其实找最长的不重叠字串是很容易的,后缀数组+二分可以在nlogn的时间内解决. 但是转调是个棘手的事情. 其实只需要o(* ̄▽ ̄*)ブ差分就可以了. 背板题. [代码] #include ...
- POJ 1743 Musical Theme 后缀数组 最长重复不相交子串
Musical ThemeTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?id=1743 Description ...
- poj 1743 Musical Theme (后缀数组+二分法)
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 16162 Accepted: 5577 De ...
- [poj 1743] Musical Theme 后缀数组 or hash
Musical Theme 题意 给出n个1-88组成的音符,让找出一个最长的连续子序列,满足以下条件: 长度大于5 不重叠的出现两次(这里的出现可以经过变调,即这个序列的每个数字全都加上一个整数x) ...
- POJ 1743 Musical Theme ( 后缀数组 && 最长不重叠相似子串 )
题意 : 给 n 个数组成的串,求是否有多个“相似”且不重叠的子串的长度大于等于5,两个子串相似当且仅当长度相等且每一位的数字差都相等. 分析 : 根据题目对于 “ 相似 ” 串的定义,我们可以将原 ...
- POJ1743 Musical Theme [后缀数组]
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 27539 Accepted: 9290 De ...
随机推荐
- Redis 报错:MISCONF Redis is configured to save RDB snapshots
MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Com ...
- BeanPostProcessor bean 的后置处理器
一. 自定 bean 的后置处理器 MyBeanPostProcessor 类.当你在初始化容器中的 bean 之前和之后,都会调用该处理器中的方法 @Component //将该后后置处理器加入到容 ...
- BA-siemens-insight使用问题汇总
insight安装完成后不要修改windows时间 1.如果在完成软件安装及授权后,更改了系统的时间,则软件会判断您电脑的时间已经更改,软件将无法启动,所以在软件完成正确安装后,禁止修改系统时间.更改 ...
- springboot配置容器
servlet容器配置 Spring Boot快速的原因除了自动配置外,另一个就是将web常用的容器也集成进来并做自动配置,让使用它的人能更快速的搭建web项目,快速的实现自己的业务目的.什么是容器? ...
- iOS 使用脚本自动化复制target
有些项目成熟以后,就会有需求自动化配置生成一个全新的项目,不需要再让开发人员手动修改工程文件,将配置化工作直接移交给运维或者配置团队去做 其实按照普通的做法,无非就是在xcode里将目标target ...
- 用jquery实现隐藏列表表单的显示关闭切换以及Ajax方式改动提交相应的那一行的改动内容。
请勿盗版,转载请加上出处http://blog.csdn.net/yanlintao1 请勿盗版,转载请加上出处http://blog.csdn.net/yanlintao1 先给大家看看图片效果,大 ...
- CocoaPods的简单介绍及安装和使用
CocoaPods的简单介绍及安装和使用 一.CocoaPods是什么? 当你开发iOS应用时,会常常使用到非常多第三方开源类库.比方JSONKit.AFNetWorking等等. 可能某个类库又 ...
- 门面模式(Facade)
一:定义 提供一个统一的接口代表子系统内部的一组接口.门面模式提供一个高层的接口,使得子系统更易于使用. 二:经验 2.1 window系统的软关机(不是直接断电)是一个过程, 它自己背后会做很多 ...
- [SCOI 2005] 栅栏
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1082 [算法] 首先二分“最多得到的符合条件的木板数”,检验时可以使用DFS,但是, ...
- 使用IDEA 创建 MAVEN 项目
一,项目创建 1.File---New---project 选择maven 勾选Create from archtype,找到并选择org.apache.maven.archtype ...