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. 【WEB小工具】EncodingFilter—设置全局编码

    1.我们知道,如果是POST请求,我们需要调用request.setCharacterEncoding("utf-8") 方法来设计编码. public void doGet(Ht ...

  2. OLAP、OLTP的介绍和比较 via csdn

    OLAP.OLTP的介绍和比较 数据处理大致可以分成两大类: OLTP(On-Line Transaction Processing)联机事务处理 也称为面向交易的处理系统,其基本特征是顾客的原始数据 ...

  3. java web 学习十一(使用cookie进行会话管理)

    一.会话的概念 会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话. 有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学曾 ...

  4. Ui篇--layout_weight体验(实现按比例显示)

    在android开发中LinearLayout很常用,LinearLayout的内控件的android:layout_weight在某些场景显得非常重要,比如我们需要按比例显示.android并没用提 ...

  5. ASP.NET Session丢失的解决方案

    正常操作情况下会有ASP.NET Session丢失的情况出现.因为程序是在不停的被操作,排除Session超时的可能.另外,Session超时时间被设定成60分钟,不会这么快就超时的.现在我就把原因 ...

  6. hdfs 数据块重分布 sbin/start-balancer.sh -threshold

    数据块重分布sbin/start-balancer.sh -threshold <percentage of disk capacity>percentage of disk capa ...

  7. linux进程调度函数浅析(基于3.16-rc4)

    众所周知,进程调度使用schedule()函数来完成,下面我们从分析该函数开始,代码如下(kernel/sched/core.c): asmlinkage __visible void __sched ...

  8. 五、python使用模块

    if __name__=='__main__':用法: 当我们在命令行运行模块文件时,Python解释器把一个特殊变量__name__置为__main__,而如果在其他地方导入该hello模块时,if ...

  9. HDU4861:Couple doubi(费马小定理)

    题意: 给出k个球和质数p,对每个球以公式val(i)=1^i+2^i+...+(p-1)^i (mod p)计算出它的价值,然后两个人轮流拿,最后拿到的球的总价值大的获胜,问我们先手是否获胜. 我们 ...

  10. sqlserver 删掉日志文件ldf以后 救命语句

    sqlserver 删掉日志文件ldf以后  救命步骤: 先新建一个新数据库, 删掉新建的 .mdb 用想要还原的mdb覆盖 执行下面的语句 ALTER DATABASE 'DB_Core' SET ...