POJ1743---Musical Theme(+后缀数组二分法)
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
Use scanf instead of cin to reduce the read time.
Source
LouTiancheng@POJ
求最长不可重叠子串。能够后缀数组+二分解决
先把输入的数字前后两两做差,然后建立后缀数组。二分就可以
/*************************************************************************
> File Name: POJ1743.cpp
> Author: ALex
> Mail: zchao1995@gmail.com
> Created Time: 2015年03月31日 星期二 15时43分29秒
************************************************************************/
#include <functional>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <queue>
#include <stack>
#include <map>
#include <bitset>
#include <set>
#include <vector>
using namespace std;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
typedef long long LL;
typedef pair <int, int> PLL;
class SuffixArray
{
public:
static const int N = 20010;
int init[N];
int X[N];
int Y[N];
int Rank[N];
int sa[N];
int height[N];
int buc[N];
int size;
void clear()
{
size = 0;
}
void insert(int n)
{
init[size++] = n;
}
bool cmp(int *r, int a, int b, int l)
{
return (r[a] == r[b] && r[a + l] == r[b + l]);
}
void getsa(int m = 256)
{
init[size] = 0;
int l, p, *x = X, *y = Y, n = size + 1;
for (int i = 0; i < m; ++i)
{
buc[i] = 0;
}
for (int i = 0; i < n; ++i)
{
buc[x[i] = init[i]]++;
}
for (int i = 1; i < m; ++i)
{
buc[i] += buc[i - 1];
}
for (int i = n - 1; i >= 0; --i)
{
sa[--buc[x[i]]] = i;
}
for (l = 1, p = 1; l <= n; m = p, l *= 2)
{
p = 0;
for (int i = n - l; i < n; ++i)
{
y[p++] = i;
}
for (int i = 0; i < n; ++i)
{
if (sa[i] >= l)
{
y[p++] = sa[i] - l;
}
}
for (int i = 0; i < m; ++i)
{
buc[i] = 0;
}
for (int i = 0; i < n; ++i)
{
++buc[x[y[i]]];
}
for (int i = 1; i < m; ++i)
{
buc[i] += buc[i - 1];
}
for (int i = n - 1; i >= 0; --i)
{
sa[--buc[x[y[i]]]] = y[i];
}
int i;
for (swap(x, y), x[sa[0]] = 0, p = 1, i = 1; i < n; ++i)
{
x[sa[i]] = cmp(y, sa[i - 1], sa[i], l) ?
p - 1 : p++;
}
if (p >= n)
{
break;
}
}
}
void getheight()
{
int h = 0;
for (int i = 0; i <= size; ++i)
{
Rank[sa[i]] = i;
}
height[0] = 0;
for (int i = 0; i < size; ++i)
{
if (h > 0)
{
--h;
}
int j = sa[Rank[i] - 1];
for (; i + h < size && j + h < size && init[i + h] == init[j + h]; ++h);
height[Rank[i] - 1] = h;
}
}
bool judge(int k)
{
int maxs = sa[1], mins = sa[1];
for (int i = 1; i < size; ++i)
{
if (height[i] < k)
{
maxs = mins = sa[i + 1];
}
else
{
maxs = max(maxs, sa[i + 1]);
mins = min(mins, sa[i + 1]);
if (maxs - mins > k)
{
return 1;
}
}
}
return 0;
}
void solve()
{
int l = 1, r = size;
int mid;
int ans = 0;
while (l <= r)
{
int mid = (l + r) >> 1;
if (judge(mid))
{
l = mid + 1;
ans = mid;
}
else
{
r = mid - 1;
}
}
++ans;
printf("%d\n", ans >= 5 ? ans : 0);
}
}SA;
int val[20010];
int main()
{
int n;
while (~scanf("%d", &n), n)
{
SA.clear();
for (int i = 1; i <= n; ++i)
{
scanf("%d", &val[i]);
}
for (int i = n; i >= 2; --i)
{
val[i] = val[i] - val[i - 1] + 90;
}
for (int i = 2; i <= n; ++i)
{
SA.insert(val[i]);
}
SA.getsa();
SA.getheight();
SA.solve();
}
return 0;
}
版权声明:本文博客原创文章。博客,未经同意,不得转载。
POJ1743---Musical Theme(+后缀数组二分法)的更多相关文章
- poj 1743 Musical Theme (后缀数组+二分法)
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 16162 Accepted: 5577 De ...
- POJ1743 Musical Theme —— 后缀数组 重复出现且不重叠的最长子串
题目链接:https://vjudge.net/problem/POJ-1743 Musical Theme Time Limit: 1000MS Memory Limit: 30000K Tot ...
- POJ1743 Musical Theme [后缀数组]
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 27539 Accepted: 9290 De ...
- POJ1743 Musical Theme [后缀数组+分组/并查集]
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 27539 Accepted: 9290 De ...
- POJ1743 Musical Theme(后缀数组 二分)
Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 33462 Accepted: 11124 Description A m ...
- POJ-1743 Musical Theme(后缀数组)
题目大意:给一个整数序列,找出最长的连续变化相同的.至少出现两次并且不相重叠一个子序列. 题目分析:二分枚举长度进行判定. 代码如下: # include<iostream> # incl ...
- poj1743 Musical Theme 后缀数组的应用(求最长不重叠重复子串)
题目链接:http://poj.org/problem?id=1743 题目理解起来比较有困难,其实就是求最长有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1 ...
- [Poj1743] [后缀数组论文例题] Musical Theme [后缀数组不可重叠最长重复子串]
利用后缀数组,先对读入整数处理str[i]=str[i+1]-str[i]+90这样可以避免负数,计算Height数组,二分答案,如果某处H<lim则将H数组分开,最终分成若干块,判断每块中是否 ...
- POJ 1743 Musical Theme 后缀数组 最长重复不相交子串
Musical ThemeTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?id=1743 Description ...
- Poj 1743 Musical Theme(后缀数组+二分答案)
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 28435 Accepted: 9604 Descri ...
随机推荐
- 【Linux探索之旅】第一部分第五课:Unity桌面,人生若只如初见
内容简介 1.第一部分第五课:Unity桌面,人生若只如初见 2.第一部分第六课预告:Linux如何安装在虚拟机中 Unity桌面,人生若只如初见 不容易啊,经过了前几课的学习,我们认识了Linux是 ...
- [LeetCode101]Symmetric Tree
题目: Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). F ...
- UML学习(一)类图和对象图
对象是一个概念,一种抽象或者事物.对象能够是具有现实意义的事物,也能够是抽象的一个概念.比方,一家公司或者一个进程. 类是一组对象的集合或者抽象的概念.类具有同样的属性和方法. 介绍完基本对象和类的基 ...
- 皮尔逊相似度计算的例子(R语言)
编译最近的协同过滤算法皮尔逊相似度计算.下顺便研究R简单使用的语言.概率统计知识. 一.概率论和统计学概念复习 1)期望值(Expected Value) 由于这里每一个数都是等概率的.所以就当做是数 ...
- 【剑指offer】面试题28:弦乐
def Permutation(data, i): if len( data ) == 0: return # i stand for the start of first part for i in ...
- 解决 U盘安装Windows Server 2012 R2 报错 Windows 无法打开所需的文件 Sources\install.wim
报错原因: 使用UltraISO等软件刻录镜像时默认使用FAT32文件系统,该系统不支持大于4G的文件, 而Server 2012 R2的安装文件install.wim为5.12G,固安装失败. 解决 ...
- MySQL存储过程:用户授权量
写这些脚本需求放缓的调查记录到数据库,方便观看. 1. 因为默认mysql.slow_log表使用csv数据引擎,该数据不支持指数,因此,有必要改变MyISAM发动机.和query_time字段索引, ...
- Andrid 多线程下载
本文转自:http://www.2cto.com/kf/201205/130969.html 本文将介绍在android平台下如何实现多线程下载,大家都知道,android平台使用java做为开发语言 ...
- 2014年度辛星完全解读html部分
接下来,我们继续学习HTML标签,希望大家可以再接再厉.同一时候辛星也会支持大家.我们一起努力,一起加油. 我们本小节来认识另外几个标签. *************空格和换行************ ...
- C++ tree(1)
建立与基本操作 .有关二叉树的相关概念,这里不再赘述,假设不了解二叉树相关概念,建议先学习数据结构中的二叉树的知识点 准备数据 定义二叉树结构操作中须要用到的变量及数据等. #define MAXLE ...