题目大意:

* 有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,现在要找一个重复的主题。 * “主题”是整个音符序列的一个子串,它需要满足如下条件: * 1.长度至少为5个音符 * 2.在乐曲中重复出现(可能经过转调,“转调”的意思是主题序列中每个音符都被加上或减去了同一个整数值。) * 3.重复出现的同一主题不能有公共部分。

 

分析:也是看的论文才做的这道题,学了4天的后缀数组,终于A掉一道题了,啥也不说了,都是眼泪(怎么做可以看看论文,说的很详细)。

 

代码如下:

===============================================================================================================

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std; const int MAXN = 2e4+;
const int BaseNum = ; struct SuffixArr
{
int text[MAXN], tempx[MAXN], tempy[MAXN];
int sum[MAXN], rank[MAXN], sa[MAXN], heigh[MAXN];
int *x, *y, N, MaxId; void Insert(int mus[], int len)
{
N = len, MaxId = ;
x = tempx, y=tempy; for(int i=; i<N; i++)
{
x[i] = text[i] = mus[i];
y[i] = i;
}
}
void BaseSort()
{
for(int i=; i<MaxId; i++)
sum[i] = ;
for(int i=; i<N; i++)
sum[ x[ y[i] ] ] += ;
for(int i=; i<MaxId; i++)
sum[i] += sum[i-];
for(int i=N-; i>=; i--)
sa[ --sum[ x[ y[i] ] ] ] = y[i];
}
bool OK(int i, int len)
{
if(sa[i]+len>N || sa[i-]+len>N)
return false;
if(y[sa[i]] != y[sa[i-]] || y[sa[i]+len] != y[sa[i-]+len])
return false; return true;
}
void Build_Sa()
{
BaseSort(); for(int len=; len<N; len<<=)
{
int id = ; for(int i=N-len; i<N; i++)
y[id++] = i;
for(int i=; i<N; i++)if(sa[i]>=len)
y[id++] = sa[i] - len; BaseSort();
swap(x, y); x[ sa[] ] = id = ; for(int i=; i<N; i++)
{
if(OK(i, len) == true)
x[ sa[i] ] = id;
else
x[ sa[i] ] = ++id;
} MaxId = id+; if(MaxId >= N)break;
}
}
void GetHeight()
{
for(int i=; i<N; i++)
rank[ sa[i] ] = i; for(int k=,i=; i<N; i++)
{
if(!rank[i])
{
k = heigh[] = ;
continue;
}
if(k)k--; int pre = sa[ rank[i]- ]; while(text[pre+k] == text[i+k])
k++;
heigh[rank[i]] = k;
}
}
}; struct SuffixArr suf;
int music[MAXN]; bool Find(int k)
{
int Min, Max; Min = Max = suf.sa[]; for(int i=; i<suf.N; i++)
{
if(suf.heigh[i] < k)
Min = Max = suf.sa[i];
else
{
Min = min(Min, suf.sa[i]);
Max = max(Max, suf.sa[i]); if(Max-Min > k)
return true;
}
} return false;
} int main()
{
int i, N; while(scanf("%d", &N), N)
{
for(i=; i<N; i++)
{
scanf("%d", &music[i]);
if(i)music[i-] = music[i-]-music[i]+BaseNum;
}
music[N-] = ; suf.Insert(music, N);
suf.Build_Sa();
suf.GetHeight(); int L=, R=N/, ans=-; while(L <= R)
{
int Mid = (L+R)>>; if(Find(Mid) == true)
{
L = Mid + ;
ans = Mid;
}
else
R = Mid - ;
} printf("%d\n", ans+);
} return ;
}

Musical Theme - poj 1743(求最大不重叠重复子串)的更多相关文章

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

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

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

    求不可重叠最长重复子串 对于height[i]定义为sa[i]和 sa[i-1]的最长公共前缀 这个最长公共前缀的值肯定是最大的 证明: 设rank[j] < rank[k], 则不难证明后缀j ...

  3. Musical Theme POJ - 1743 后缀数组

    A musical melody is represented as a sequence of N (1<=N<=20000)notes that are integers in the ...

  4. poj 1961 (求字符串中的重复子串)

    Sample Input 3aaa12aabaabaabaab0Sample Output Test case #12 23 3 Test case #22 2 //aa有2个a6 2 //aabaa ...

  5. POJ 1743 Musical Theme (后缀数组,求最长不重叠重复子串)(转)

    永恒的大牛,kuangbin,膜拜一下,Orz 链接:http://www.cnblogs.com/kuangbin/archive/2013/04/23/3039313.html Musical T ...

  6. poj1743 Musical Theme 后缀数组的应用(求最长不重叠重复子串)

    题目链接:http://poj.org/problem?id=1743 题目理解起来比较有困难,其实就是求最长有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1 ...

  7. poj 1743 后缀数组 求最长不重叠重复子串

    题意:有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,现在要找一个重复的主题. “主题”是整个音符序列的一个子串,它需要满足如下条件:1 ...

  8. ACdream 1430——SETI——————【后缀数组,不重叠重复子串个数】

    SETI Time Limit: 4000/2000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) Submit Statist ...

  9. hdu_2668 Daydream O(n)求最长不重复子串

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2668 Daydream Time Limit: 2000/1000 MS (Java/Others)  ...

随机推荐

  1. Object-c 创建对象

    创建对象有两种方法: 1. NSString *str = [NSString string]; 2. NSString *myStr = [[NSString alloc]init]; 第一种创建方 ...

  2. Eclipse不能自动编译 java文件,不会生成CLASS

    每次修改类代码后都得重启 Tomcat 花了1天终于解决,网上所说基本是下面1和2的方法,使用之后还是不行最后重新建工作环境导入项目对比了一下找到第三种方法 1.Project 下有个 "B ...

  3. python中的“引用”和C++的引用

    python并不刻意区分“按值传递”和“按引用传递”. 在底层,python将值分为不可变对象(比如int,str)和可变对象(比如列表).所有的变量都是对某个对象的引用,赋值(=)和函数参数传递,都 ...

  4. 滑动开关效果 css3滑动开关】纯CSS3代码实现滑动开关效果-css3滑动效果-css3左右滑动

    今天看到一篇有关 css3事件的博文,一时兴起便整理下相关的资料. 点击按钮,可以实现开关的滑动效果. 今天看到一篇有关 css3事件的博文,一时兴起便整理下相关的资料. 点击按钮,可以实现开关的滑动 ...

  5. StringBuilder字符串拼接类

    StringBuilder StringBuilder是在using System.Text命名空间下的一个成员. 在做字符串拼接的时候,因为字符串是引用类型,新的字符串是会再内存中创建的,所以用+号 ...

  6. yii2源码学习笔记(九)

    Application是所有应用程序类的基类,接下来了解一下它的源码.yii2\base\Application.php. <?php /** * @link http://www.yiifra ...

  7. php 扩展编译linux

    进入扩展库目录:$cd phpredis-master 需要root权限执行 执行:$ phpize 执行:$ ./configure 执行:$ make 执行:$ make install   编译 ...

  8. Start an installation from GRUB

    Start an installation from GRUB Description This tip will show you how to start an installation for ...

  9. maya 写UI 用到的工具

    import os cmds.window() scrollLayout = cmds.scrollLayout(w=150) cmds.gridLayout( numberOfColumns=30, ...

  10. VisualSVN Server 从此告别SVN记事本配置

    http://www.visualsvn.com/downloads/ 注意下载的是Server版本,他还会提供一个visual Studio的插件:   安装完毕后,可以在管理界面进行角色添加,创建 ...