Musical Theme

人生第一道后缀数组的题,采用大众化思想姿势极其猥琐。

题意:给你n个数,问其中是否存在一个子序列,这个子序列加上或者减去一个数与另一个子序列一样。要求两个子序列不能有重叠的部分。求这个子序列最长的长度。

思路:有点像KMP,先将所有的数之间的差(再加上88)存在一个数组中,然后对这个数组进行构造后缀数组。我们知道height[]数组的含义是:排名为i的这个后缀与排名为i-1的这个后缀的最长公共前缀。而我们要求的是不重叠,怎么解决这个问题呢 ,我们可以二分答案,将问题变成二分判定型。引用罗穗骞的论文:

先二分答案,把题目变成判定性问题:判断是否存在两个长度为k的子串是相同的,且不重叠。解决这个问题的关键还是利用height数组。把排序后的后缀分成若干组,其中每组的后缀之间的height值都不小于k。容易看出,有希望成为最长公共前缀不小于k的两个后缀一定在同一组。然后对于每组后缀,只须判断每个后缀的sa值的最大值和最小值之差是否不小于k。如果有一组满足,则说明存在,否则不存在。整个做法的时间复杂度为O(nlogn)。

需要注意的是此题m的范围是88*2。

int a[N],s[N];
int sa[N],t[N],t1[N],c[N],n,m=88*3;
void build()
{
int i,*x=t,*y=t1;
memset(c,0,sizeof(c));
for(i=0; i<n; i++) c[x[i]=s[i]]++;
for(i=1; i<m; i++) c[i]+=c[i-1];
for(i=n-1; i>=0; i--) sa[--c[x[i]]]=i;
for(int k=1; k<=n; k<<=1)
{
int p=0;
for(i=n-k; i<n; i++) y[p++]=i;
for(i=0; i<n; i++) if(sa[i]>=k) y[p++]=sa[i]-k; memset(c,0,sizeof(c));
for(i=0; i<n; i++) c[x[y[i]]]++;
for(i=1; i<m; i++) c[i]+=c[i-1];
for(i=n-1; i>=0; i--) sa[--c[x[y[i]]]]=y[i];
swap(x,y);
p=1,x[sa[0]]=0;
for(i=1; i<n; i++)
x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
if(p>=n) break;
m=p;
}
}
int Rank[N],height[N];
void get_height()
{
int k=0;
for(int i=0;i<n;i++) Rank[sa[i]]=i;
for(int i=0;i<n;i++)
{
if(k) k--;
int j=sa[Rank[i]-1];
while(s[i+k]==s[j+k]) k++;
height[Rank[i]]=k;
}
}
int find(int k)
{
int i=1;
while(i<=n)
{
while(i<=n&&height[i]<k) i++;
if(i>n) return 0;
int ma=sa[i-1],mi=sa[i-1];
while(i<=n&&height[i]>=k)
{
ma=max(ma,sa[i]);
mi=min(mi,sa[i]);
i++;
}
if(ma-mi>=k) return 1;
}
return 0;
}
int main()
{
while(~scanf("%d",&n)&&n)
{
for(int i=0;i<n;i++) scanf("%d",&a[i]);
for(int i=0;i<n-1;i++) s[i]=a[i+1]-a[i]+88;
n--;
build();
get_height();
int l=0,r=n/2;
while(l<r)
{
int mid=(l+r+1)/2;
if(find(mid)) l=mid;
else r=mid-1;
}
l=l>=4?l+1:0;
printf("%d\n",l);
}
return 0;
}

心力交瘁。。。。。。卒

POJ-1743 Musical Theme,后缀数组+二分!的更多相关文章

  1. Poj 1743 Musical Theme (后缀数组+二分)

    题目链接: Poj  1743 Musical Theme 题目描述: 给出一串数字(数字区间在[1,88]),要在这串数字中找出一个主题,满足: 1:主题长度大于等于5. 2:主题在文本串中重复出现 ...

  2. Poj 1743 Musical Theme(后缀数组+二分答案)

    Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 28435 Accepted: 9604 Descri ...

  3. POJ 1743 Musical Theme ——后缀数组

    [题目分析] 其实找最长的不重叠字串是很容易的,后缀数组+二分可以在nlogn的时间内解决. 但是转调是个棘手的事情. 其实只需要o(* ̄▽ ̄*)ブ差分就可以了. 背板题. [代码] #include ...

  4. POJ 1743 Musical Theme 后缀数组 最长重复不相交子串

    Musical ThemeTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?id=1743 Description ...

  5. poj 1743 Musical Theme (后缀数组+二分法)

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 16162   Accepted: 5577 De ...

  6. [poj 1743] Musical Theme 后缀数组 or hash

    Musical Theme 题意 给出n个1-88组成的音符,让找出一个最长的连续子序列,满足以下条件: 长度大于5 不重叠的出现两次(这里的出现可以经过变调,即这个序列的每个数字全都加上一个整数x) ...

  7. POJ 1743 Musical Theme ( 后缀数组 && 最长不重叠相似子串 )

    题意 : 给 n 个数组成的串,求是否有多个“相似”且不重叠的子串的长度大于等于5,两个子串相似当且仅当长度相等且每一位的数字差都相等. 分析 :  根据题目对于 “ 相似 ” 串的定义,我们可以将原 ...

  8. POJ.1743.Musical Theme(后缀数组 倍增 二分 / 后缀自动机)

    题目链接 \(Description\) 给定一段数字序列(Ai∈[1,88]),求最长的两个子序列满足: 1.长度至少为5 2.一个子序列可以通过全部加或减同一个数来变成另一个子序列 3.两个子序列 ...

  9. POJ 1743 Musical Theme 后缀数组 不可重叠最长反复子串

    二分长度k 长度大于等于k的分成一组 每组sa最大的和最小的距离大于k 说明可行 #include <cstdio> #include <cstring> #include & ...

  10. POJ 1743 [USACO5.1] Musical Theme (后缀数组+二分)

    洛谷P2743传送门 题目大意:给你一个序列,求其中最长的一对相似等长子串 一对合法的相似子串被定义为: 1.任意一个子串长度都大于等于5 2.不能有重叠部分 3.其中一个子串可以在全部+/-某个值后 ...

随机推荐

  1. error c2243:"类型转换" 转换存在,但无法访问

    今天在程序的中有一段class Quackable : QuackObservable,结果一直出现error c2243:"类型转换" 转换存在,但无法访问. 后来发现只要改成c ...

  2. c语言中的赋值

    int s,i,len,err=0 这个是只给err赋了值还是这四个都有?

  3. (1)Ngixn 编译安装 (版本:1.12.1)

        1.创建用户和群组     groupadd nginx     创建一个用户,不允许登陆和不创主目录     useradd -s /sbin/nologin -g nginx -M ngi ...

  4. An internal error occurred during: "Map/Reduce location status updater". java.lang.NullPointerException

    eclipse配置hadoop 2.6 服务器做的虚拟机,因为window是的hadoop会出现意想不到的错误,因为,我做了ubuntu的虚拟机供我使用 在虚拟机中进行映射设置 在eclipse中dr ...

  5. 字符串赋值方式理解 sizeof 和strlen的一些区别

    #include<stdio.h>#include<string.h>  int main(){ int a,i=0; char ch[10000]; while(scanf( ...

  6. selenium+chrome浏览器驱动-爬取百度图片

    百度图片网页中中,当页面滚动到底部,页面会加载新的内容. 我们通过selenium和谷歌浏览器驱动,执行js,是浏览器不断加载页面,通过抓取页面的图片路径来下载图片. from selenium im ...

  7. springmvc导出excel(POI)

    /** * 导出excel表格 */ @RequestMapping(value = "/doExportData", method = {RequestMethod.POST, ...

  8. 响应式Web设计- 背景图片

    背景图片可以响应式调整大小或缩放,以下是三种不同的方式 1.如果 background-size 属性设置为 "contain", 背景图片将按比例自适应内容区域.图片保持其比例不 ...

  9. webpack4.x加vue模板文件简单还原vue-cli

    1.首先 npm init -y 创建一个项目 2.安装vue npm install vue --save 3.然后安装webpack 注意如果全局没有还要安装全局的webpack和webpack- ...

  10. BZOJ3301 P2524 UVA11525 算法解释康托展开

    这三个题的代码分别对应第二个第一个第三个 在刘汝佳蓝书上我遇到了这个康托展开题. 当时去了解了一下,发现很有意思 百度上的康托展开定义 原理介绍 编辑 康托展开运算 其中, 为整数,并且 . 的意义为 ...