看来对height数组进行分段确实是个比较常用的技巧。

题意:

一个主题是可以变调的,也就是如果这个主题所有数字加上或者减少相同的数值,可以看做是相同的主题。

一个主题在原串中至少要出现两次,而且一定要有不相交的两次。

因为说了可以变调,所以我们处理每相邻两项的差值,这样就得到n-1个数字。然后找最大的不相交重复的连续子序列即可。

找这样的子序列还是要二分子序列的长度k,然后根据k对height进行分段,如果某一段的最大的sa值与最小的sa值相差超过k的话便符合要求。

然后强调一下几个容易出错的地方:

  • 前面说一定要超过k才行,下面解释下为什么等于k是不可以的。比如说n=5, 序列为 0 3 8 11 16.求出相邻两项的差值为3 5 3 5,很明显子序列3 5是一个不相交的重复序列,但是第一个3 5 对应原序列的0 3 8,第二个3 5 对应原序列的 8 11 16. 显然,这有重叠的部分了。
  • 我们在求出相邻两项差值的序列中找到最长不相交子序列后,假设长度为k,那么对应原序列中子序列的长度为k + 1
 #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = + ;
const int INF = ;
int n; struct SuffixArray
{
int s[maxn];
int sa[maxn];
int rank[maxn];
int height[maxn];
int t[maxn], t2[maxn], c[maxn];
int n; void clear() { n = ; memset(sa, , sizeof(sa)); } void build_sa(int m)
{
int i, *x = t, *y = t2;
for(i = ; i < m; i++) c[i] = ;
for(i = ; i < n; i++) c[x[i] = s[i]]++;
for(i = ; i < m; i++) c[i] += c[i - ];
for(i = n - ; i >= ; i--) sa[--c[x[i]]] = i;
for(int k = ; k <= n; k <<= )
{
int p = ;
for(i = n - k; i < n; i++) y[p++] = i;
for(i = ; i < n; i++) if(sa[i] >= k) y[p++] = sa[i] - k;
for(i = ; i < m; i++) c[i] = ;
for(i = ; i < n; i++) c[x[y[i]]]++;
for(i = ; i < m; i++) c[i] += c[i - ];
for(i = n - ; i >= ; i--) sa[--c[x[y[i]]]] = y[i];
swap(x, y);
p = ; x[sa[]] = ;
for(i = ; i < n; i++)
x[sa[i]] = y[sa[i]]==y[sa[i-]] && y[sa[i]+k]==y[sa[i-]+k] ? p - : p++;
if(p >= n) break;
m = p;
}
} void build_height()
{
int i, j, k = ;
for(i = ; i < n; i++) rank[sa[i]] = i;
for(i = ; i < n; i++)
{
if(k) k--;
j = sa[rank[i] - ];
while(s[i + k] == s[j + k]) k++;
height[rank[i]] = k;
}
}
}; SuffixArray sa; bool ok(int len)
{
int Max, Min;
Max = Min = sa.sa[];
for(int i = ; i < n; i++)
{
if(sa.height[i] < len) Max = Min = sa.sa[i];
else
{
Max = max(Max, sa.sa[i]);
Min = min(Min, sa.sa[i]);
if(Max - Min > len) return true;
}
}
return false;
} int solve()
{
int L = , R = n / , M;
while(L < R)
{
M = (L + R + ) / ;
if(ok(M)) L = M;
else R = M - ;
}
return L;
} int main()
{
//freopen("in.txt", "r", stdin); while(scanf("%d", &n) == && n)
{
sa.clear(); int pre, now; scanf("%d", &pre);
n--;
for(int i = ; i < n; i++)
{
scanf("%d", &now);
sa.s[i] = now - pre + ;
pre = now;
}
sa.s[n] = ;
sa.n = n;
sa.build_sa();
sa.build_height();
int ans = solve();
printf("%d\n", ans >= ? ans + : );
} return ;
}

代码君

POJ 1743 (后缀数组 二分) Musical Theme的更多相关文章

  1. Musical Theme POJ - 1743 后缀数组

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

  2. POJ 1743 后缀数组

    题目链接:http://poj.org/problem?id=1743 题意:给定一个钢琴的音普序列[值的范围是(1~88)],现在要求找到一个子序列满足 1,长度至少为5 2,序列可以转调,即存在两 ...

  3. POJ 1743 (后缀数组+不重叠最长重复子串)

    题目链接: http://poj.org/problem?id=1743 题目大意:楼教主の男人八题orz.一篇钢琴谱,每个旋律的值都在1~88以内.琴谱的某段会变调,也就是说某段的数可以加减一个旋律 ...

  4. poj 1743 后缀数组 最长不重叠子串

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 30941   Accepted: 10336 D ...

  5. POJ 2774 后缀数组 || 二分+哈希

    Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 35607   Accepted: 14 ...

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

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

  7. [八分之一的男人]POJ - 1743 后缀数组 height分组 带详解

    题意:求最长不可重叠的相同差值子串的长度 这道题算是拖了好几个月,现在花了点时间应该搞懂了不少,尝试分析一下 我们首先来解决一个退化的版本,求最长不可重叠的相同子串(差值为0) 比如\(aabaaba ...

  8. POJ 3261 (后缀数组 二分) Milk Patterns

    这道题和UVa 12206一样,求至少重复出现k次的最长字串. 首先还是二分最长字串的长度len,然后以len为边界对height数组分段,如果有一段包含超过k个后缀则符合要求. #include & ...

  9. POJ 3261 后缀数组+二分

    思路: 论文题- 二分+对后缀分组 这块一开始不用基数排序 会更快的(其实区别不大) //By SiriusRen #include <cstdio> #include <cstri ...

随机推荐

  1. HDOJ 1062 Text Reverse

    Text Reverse Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tota ...

  2. Sublime Text3激活 破解

    Sublime Text 是一个复杂的文本.代码编辑器.出色用户界面,非凡的功能和惊人的性能. Sublime Text 3 官方网站 http://www.sublimetext.com/ 点击菜单 ...

  3. [读]剑指offer

    研二的开始找工作了,首先祝愿他们都能够找到自己满意的工作.看着他们的身影,自问明年自己这个时候是否可以从容面对呢?心虚不已,赶紧从老严那儿讨来一本<剑指offer>.在此顺便将自己做题所想 ...

  4. C# 和Jsonp的一个小demo 用jQuery与JSONP轻松解决跨域访问的问题

    客服端:      在A项目下面 建立一个 JsonpClient.aspx页面,代码如下: <%@ Page Language="C#" AutoEventWireup=& ...

  5. HDU 1026 Ignatius and the Princess I (BFS)

    题目链接 题意 : 从(0,0)点走到(N-1,M-1)点,问最少时间. 思路 : BFS..... #include <stdio.h> #include <string.h> ...

  6. 传说中的WCF(3):多个协定

    我们知道,WCF服务端是先定义服务协定,其实就是一个接口,然后通过实现接口来定义服务类.那么,有一个问题,如果一个服务类同时实现N个接口(也就是有N个协定)呢?结果会如何? 不必猜,我们还是通过实验来 ...

  7. mysql变量使用总结

    set语句的学习: 使用select定义用户变量的实践将如下语句改成select的形式: set @VAR=(select sum(amount) from penalties);我的修改: sele ...

  8. ActiveMQ和Tomcat的整合应用(转)

    转自:http://topmanopensource.iteye.com/blog/1111321 ActiveMQ和Tomcat的整合应用 博客分类: ActiveMQ学习和研究   在Active ...

  9. Java:装饰设计模式

    装饰设计模式: 当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能, 并提供加强功能,那么自定义的该类就称为装饰类. 装饰类通常通过构造方法接收被装饰的对象,并基于被装饰的对 ...

  10. HTML5塔防游戏——《三国塔防》 - Yorhom's Game Box

    h3{ font-size:20px; } HTML5塔防游戏--<三国塔防> 游戏介绍: <三国塔防>是一款基于HTML5和Javascript的2D塔防游戏.游戏中除了塔防 ...