Pku1743 Musical Theme详细解题报告后缀数组求不重叠的最长重复子串
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Pku1743 Musical Theme
/*
Name: pku1743
Copyright: ecjtu_acm
Author: yimao
Date: 16/02/11 13:35
Description: 二分答案,
后缀数组求不重叠的最长重复子串
*/
一、题目
Description
A musical melody is represented as a sequence of N (1<=N<=20000)notes that are integers in the range 1..88, each representing a key on the piano. It is unfortunate but true that this representation of melodies ignores the notion of musical timing; but, this programming task is about notes and not timings.
Many composers structure their music around a repeating &qout;theme&qout;, which, being a subsequence of an entire melody, is a sequence of integers in our representation. A subsequence of a melody is a theme if it:
∙is at least five notes long
∙appears (potentially transposed -- see below) again somewhere else in the piece of music
∙is disjoint from (i.e., non-overlapping with) at least one of its other appearance(s)
Transposed means that a constant positive or negative value is added to every note value in the theme subsequence.
Given a melody, compute the length (number of notes) of the longest theme.
One second time limit for this problem's solutions!
Input
The input contains several test cases. The first line of each test case contains the integer N. The following n integers represent the sequence of notes.
The last test case is followed by one zero.
Output
For each test case, the output file should contain a single line with a single integer that represents the length of the longest theme. If there are no themes, output 0.
Sample Input
30
25 27 30 34 39 45 52 60 69 79 69 60 52 45 39 34 30 26 22 18 82 78 74 70 66 67 64 60 65 80
Sample Output
5
Hint
Use scanf instead of cin to reduce the read time.
Source
LouTiancheng@POJ
二、题目大意及分析
【前话】
我的poj第200题;
楼教主男人八题之一;
3xian在status里以绝对的时空优势排第一;
纪念我的百度空间访问量破2000;
我的第一道后缀数组题;
典型的二分答案,用后缀数组求不重叠的最长重复子串;
网上看题解不下10篇,综合之后才知道他们大概在说些什么,感叹前人栽树,后人乘凉;可以证明本篇文章应该是字数最多的pku1743题解了;
【题意】
给定一个正整数N(N<=20000),然后是N个整数xi,(1<=xi<=88, 1<=i<=N)组成一个有序
的整数序列;问这个序列中存在的最长一个符合条件的子序列长度是多少,符合的条件是
1、子序列A长度至少为5;
2、有另外一个子序列B,且A、B二者没有相交部分(即不存在xi同时在A,B里出现,这
里针对下标而言,A,B的元素在整个序列里下标都不一样);
3、A,B的长度一样,设x[i],…x[i+k],x[j],…x[j+k],那么要求
(x[j]-x[i])=(x[j+1]-x[i+1])=…=(x[i+k],x[j+k]);即按下标对应的元素差值要相等,差值可以是0,1,2,-1,-2……;当然,为了满足2,(i+k)
举例说明:
例1:1 3 5 3 5 7 答案是3,(对应差值是2,如果是3 5和3 5对应,则长度是2,求的是存在的最长长度)
例2:1 2 3 4 1 2 3 4答案是4,(对应差值是0)
例3:2 2 2 2 2 2 2 2答案是4;(对应差值是0)
如果找到了最长的长度大于或等于5则输出之,否则全部输出0,所以上面三个例子都应该输出0.
大部分题解都说是求不重叠的最长重复子串;
【分析】
看下面的基本要求,你看过了那片后缀数组的论文,知道那三个数组是什么就可以;
1、预处理:
因为本题的重复也包含对应元素差值相等这一情况,所以我们要预处理出这样一个串来便于我们用一般求最长重复子串长度的方法来求解。
具体做法,输入的数字按顺序,两两做差+88放到数组r[]中,这样就有n-1个数保存了下来,在最后取r[n-1]=0(补0是论文里论述的),此时共n个数了(下标是从0开始保存的);
道理:
(很纳闷网上居然没人写这个道理,就是随口一说)
假设输入序列是c[i],那么我们如果有两个满足条件的子序列a[i],a[i+1],…a[i+k],和b[i],b[i+1],…b[i+k],则有:
b[i]-a[i]= b[i+1]-a[i+1]= …b[i+k]-a[i+k];
对前两项有:b[i+1]-b[i]=a[i+1]-a[i],即r[j]=r[k],(j!=k,具体就不确定了,不举例了)
注意到上面一定是互逆的,也就是说我们在处理出来的r[]数组中如果找出了r[j]=r[k],那么一点可以推出原来的序列里存在长度为2的满足条件的序列。推广一下,如果r[]数组里找的长度不是1,而是2的话,那么原来序列所求的长度就是3了……
2、求出SA[]数组,rank[]数组,height[]数组,这是论文里介绍的部分,算是模板。
3、二分答案;
二分答案是指答案不好直接确定,是一个存在性的问题,就可以在满足条件的范围内二分枚举可能的答案,例如要求最大值,则每次对于mid,进行判定是否满足条件,如果满足另l=mid,继续二分,就可以快速找到答案了。那么在本题,长度范围就是[0,n/2],因为是不可重叠嘛,所以最长只能到n/2了,二分枚举每一个答案,进行判定。是否这题一定要二分答案呢?等我水平上去了再论述吧。我二分写过各种,几乎每次都是调试几个小时。