Musical Theme - poj 1743(求最大不重叠重复子串)
题目大意:
* 有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(求最大不重叠重复子串)的更多相关文章
- POJ 1743 Musical Theme ( 后缀数组 && 最长不重叠相似子串 )
题意 : 给 n 个数组成的串,求是否有多个“相似”且不重叠的子串的长度大于等于5,两个子串相似当且仅当长度相等且每一位的数字差都相等. 分析 : 根据题目对于 “ 相似 ” 串的定义,我们可以将原 ...
- Musical Theme POJ - 1743(后缀数组+二分)
求不可重叠最长重复子串 对于height[i]定义为sa[i]和 sa[i-1]的最长公共前缀 这个最长公共前缀的值肯定是最大的 证明: 设rank[j] < rank[k], 则不难证明后缀j ...
- Musical Theme POJ - 1743 后缀数组
A musical melody is represented as a sequence of N (1<=N<=20000)notes that are integers in the ...
- poj 1961 (求字符串中的重复子串)
Sample Input 3aaa12aabaabaabaab0Sample Output Test case #12 23 3 Test case #22 2 //aa有2个a6 2 //aabaa ...
- POJ 1743 Musical Theme (后缀数组,求最长不重叠重复子串)(转)
永恒的大牛,kuangbin,膜拜一下,Orz 链接:http://www.cnblogs.com/kuangbin/archive/2013/04/23/3039313.html Musical T ...
- poj1743 Musical Theme 后缀数组的应用(求最长不重叠重复子串)
题目链接:http://poj.org/problem?id=1743 题目理解起来比较有困难,其实就是求最长有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1 ...
- poj 1743 后缀数组 求最长不重叠重复子串
题意:有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,现在要找一个重复的主题. “主题”是整个音符序列的一个子串,它需要满足如下条件:1 ...
- ACdream 1430——SETI——————【后缀数组,不重叠重复子串个数】
SETI Time Limit: 4000/2000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) Submit Statist ...
- hdu_2668 Daydream O(n)求最长不重复子串
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2668 Daydream Time Limit: 2000/1000 MS (Java/Others) ...
随机推荐
- 图像显示 imshow()[OpenCV 笔记5]
void imshow(const string& winname InputArray mat); winname 窗口表识名称 mat 需要显示的图像.InputArray类型,声明如下 ...
- IO流基础加强
字节流对象:InputStream,OutputStream 缓冲字节流对象:BufferedInputStream , BufferedOutputStream 用法和字符流对象一样,但也有区别, ...
- C++静态成员函数访问非静态成员的几种方法
大家都知道C++中类的成员函数默认都提供了this指针,在非静态成员函数中当你调用函数的时候,编译器都会“自动”帮你把这个this指针加到函数形参里去.当然在C++灵活性下面,类还具备了静态成员和静态 ...
- Dreamweaver安装jQuery插件jQuery_API.mxp
要让Dreamweaver支持jQuery自动提示代码功能,方法很简单,下载一个插件—jQuery_API.mxp[点击下载]. 在Dreamweaver里依次选择“命令” -> “扩展管理” ...
- [WinJS] Promise 用法
初学 WinJS, 可能对 Promise 的用法不大清楚,本文简要说明一下 WinJS中 promise 的基本用法. 主要参考自:http://try.buildwinjs.com/#promis ...
- iOS: 学习笔记, 添加一个带界面约束的控制器
1. 创建一个空iOS应用程序(Empty Application). 2. 添加加控制器类. 修改控制器类的viewDidLoad - (void)viewDidLoad { [super view ...
- git 创建多个账户ssh
创建一个账户 创建ssh本地秘钥. $ ssh-keygen -t rsa -C "youremail@xxx.com" 一路回车,会在~/.ssh/目录下生成id_rsa和id_ ...
- dubbo 负载均衡中策略决策
在dubbo中的服务端负载均衡配置,如果像以下情况,将需要决策最终的负载策略问题: <dubbo:application name="hello-world-server" ...
- MongoDB update数据语法【转】
在前面的文章“mongodb 查询的语法”里,我介绍了Mongodb的常用查询语法,Mongodb的update操作也有点复杂,我结合自己的使用经验,在这里介绍一下,给用mongodb的朋友看看,也方 ...
- 抓取天涯文章的蜘蛛代码,刚经过更新(因为天涯页面HTML代码变化)
#_*_coding:utf-8-*- import urllib2 import traceback import codecs from BeautifulSoup import Beautifu ...