Musical Theme
Time Limit: 20 Sec

Memory Limit: 256 MB

题目连接

http://poj.org/problem?id=1743

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
0

Sample Output

5

HINT

题意

让你找到最长的不相交重复子串

题解

后缀数组,跑出height数组之后,然后直接二分然后O(n),check就好了

代码:

//qscqesze
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <typeinfo>
#include <fstream>
#include <map>
#include <stack>
typedef long long ll;
using namespace std;
//freopen("D.in","r",stdin);
//freopen("D.out","w",stdout);
#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
#define maxn 25000
#define mod 10007
#define eps 1e-9
int Num;
char CH[];
//const int inf=0x7fffffff; //нчоч╢С
const int inf=0x3f3f3f3f;
inline ll read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
//************************************************************************************** int s[*maxn];
int a[maxn];
int n;
int sa[maxn], rank[maxn], height[maxn];
int wa[maxn], wb[maxn], wv[maxn], wd[maxn]; int cmp(int *r, int a, int b, int l){
return r[a] == r[b] && r[a+l] == r[b+l];
} void build_sa(int *r, int n, int m){ // 倍增算法 r为待匹配数组 n为总长度 m为字符范围
int i, j, p, *x = wa, *y = wb, *t;
for(i = ; i < m; i ++) wd[i] = ;
for(i = ; i < n; i ++) wd[x[i]=r[i]] ++;
for(i = ; i < m; i ++) wd[i] += wd[i-];
for(i = n-; i >= ; i --) sa[-- wd[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 ++) wd[i] = ;
for(i = ; i < n; i ++) wd[wv[i]] ++;
for(i = ; i < m; i ++) wd[i] += wd[i-];
for(i = n-; i >= ; i --) sa[-- wd[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 ++;
}
}
} void calHeight(int *r, int n){ // 求height数组。
int i, j, k = ;
for(i = ; i <= n; i ++) rank[sa[i]] = i;
for(i = ; i < n; height[rank[i ++]] = k){
for(k ? k -- : , j = sa[rank[i]-]; r[i+k] == r[j+k]; k ++);
}
}
int check(int mid)
{
int Minn=sa[],Maxn=sa[];
for(int i=;i<=n;i++)
{
if(height[i]>=mid)
{
Minn=min(sa[i],Minn);
Maxn=max(sa[i],Maxn);
if(Maxn-Minn>mid)
return ;
}
else
Minn=Maxn=sa[i];
}
return ;
}
void init()
{
memset(a,,sizeof(a));
memset(s,,sizeof(s));
memset(sa,,sizeof(sa));
memset(rank,,sizeof(rank));
memset(height,,sizeof(height));
memset(wa,,sizeof(wa));
memset(wb,,sizeof(wb));
memset(wv,,sizeof(wv));
memset(wd,,sizeof(wd));
}
int main()
{
while(cin>>n)
{
if(n==)
break;
init();
for(int i=;i<n;i++)
a[i]=read();
n--;
for(int i=;i<n;i++)
s[i]=a[i+]-a[i]+;
s[n]=;
build_sa(s,n+,);
calHeight(s,n);
int l=,r=n,ans=;
while(l<=r)
{
int mid=(l+r)>>;
if(check(mid))
{
ans=max(ans,mid);
l=mid+;
}
else
r=mid-;
}
if(ans<)
ans=;
else
ans++;
cout<<ans<<endl;
}
}

POJ 1743 Musical Theme 后缀数组 最长重复不相交子串的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. poj 1743 Musical Theme 后缀自动机/后缀数组/后缀树

    题目大意 直接用了hzwer的题意 题意:有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,现在要找一个重复的主题."主题&qu ...

随机推荐

  1. 【转】第一次使用Android Studio时你应该知道的一切配置

    原文网址:http://www.cnblogs.com/smyhvae/p/4390905.html [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.c ...

  2. Asp.Net Core(.net内核)

    Asp.Net Core(.net内核) //----------------Day1----------------一章    Web基本原理 1节课程说明 web窗体--设计界面--加法使用Chr ...

  3. Selenium - IDE模式匹配

    Selenium - IDE模式匹配 在Selenium IDE中,如定位器,模式是selenium中经常使用的一种类型的参数.它允许用户描述特殊字符的模式.很多时候,我们想核实文字是动态的,在这种情 ...

  4. qt集成到vs2010

    因为要正式开始学习图形处理相关的知识了,所以要搭建开发平台.我所要用到的平台主要是vs和qt.虽然现在已经出了vs2013了,并且外观看起来特别漂亮,但是我所要用到的qt4版本中,没有对于的qtAdd ...

  5. bzoj 2502 清理雪道(有源汇的上下界最小流)

    [题意] 有一个DAG,要求每条边必须经过一次,求最少经过次数. [思路] 有上下界的最小流.  边的下界为1,上界为无穷.构造可行流模型,先不加ts边跑一遍最大流,然后加上t->s的inf边跑 ...

  6. 修改 myeclipse8.5 servlet 模板

    在myeclipse8.5的安装目录下找到 \Common\plugins下的com.genuitec.eclipse.wizards_8.5.0.zmyeclipse75020090612.jar ...

  7. [Hive - LanguageManual] Select base use

    Select Syntax WHERE Clause ALL and DISTINCT Clauses Partition Based Queries HAVING Clause LIMIT Clau ...

  8. C# 颜色转换

    十六进制颜色与Color对象的互相转换[C#]   C#十六进制颜色与Color对象的互相转换 把十六进制颜色转化为color对象ColorTranslator.FromHtml("#FF0 ...

  9. leetcode@ [316] Remove Duplicate Letters (Stack & Greedy)

    https://leetcode.com/problems/remove-duplicate-letters/ Given a string which contains only lowercase ...

  10. SQL Server 跨库连接

    -- 开启组件 reconfigure reconfigure -- 关闭组件 reconfigure reconfigure -- 查询远程数据库 SELECT * FROM OPENDATASOU ...