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;
}

$(function () {
$('pre.prettyprint code').each(function () {
var lines = $(this).text().split('\n').length;
var $numbering = $('

    ').addClass('pre-numbering').hide();
    $(this).addClass('has-numbering').parent().append($numbering);
    for (i = 1; i ').text(i));
    };
    $numbering.fadeIn(1700);
    });
    });

    版权声明:本文博客原创文章。博客,未经同意,不得转载。

POJ1743---Musical Theme(+后缀数组二分法)的更多相关文章

  1. poj 1743 Musical Theme (后缀数组+二分法)

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 16162   Accepted: 5577 De ...

  2. POJ1743 Musical Theme —— 后缀数组 重复出现且不重叠的最长子串

    题目链接:https://vjudge.net/problem/POJ-1743 Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Tot ...

  3. POJ1743 Musical Theme [后缀数组]

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 27539   Accepted: 9290 De ...

  4. POJ1743 Musical Theme [后缀数组+分组/并查集]

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 27539   Accepted: 9290 De ...

  5. POJ1743 Musical Theme(后缀数组 二分)

    Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 33462   Accepted: 11124 Description A m ...

  6. POJ-1743 Musical Theme(后缀数组)

    题目大意:给一个整数序列,找出最长的连续变化相同的.至少出现两次并且不相重叠一个子序列. 题目分析:二分枚举长度进行判定. 代码如下: # include<iostream> # incl ...

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

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

  8. [Poj1743] [后缀数组论文例题] Musical Theme [后缀数组不可重叠最长重复子串]

    利用后缀数组,先对读入整数处理str[i]=str[i+1]-str[i]+90这样可以避免负数,计算Height数组,二分答案,如果某处H<lim则将H数组分开,最终分成若干块,判断每块中是否 ...

  9. POJ 1743 Musical Theme 后缀数组 最长重复不相交子串

    Musical ThemeTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?id=1743 Description ...

  10. Poj 1743 Musical Theme (后缀数组+二分)

    题目链接: Poj  1743 Musical Theme 题目描述: 给出一串数字(数字区间在[1,88]),要在这串数字中找出一个主题,满足: 1:主题长度大于等于5. 2:主题在文本串中重复出现 ...

随机推荐

  1. poj 2236:Wireless Network(并查集,提高题)

    Wireless Network Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 16065   Accepted: 677 ...

  2. LCIS POJ 2172 Greatest Common Increasing Subsequence

    题目传送门 题意:LCIS(Longest Common Increasing Subsequence) 最长公共上升子序列 分析:a[i] != b[j]: dp[i][j] = dp[i-1][j ...

  3. hdu 5437 Alisha’s Party 模拟 优先队列

    Problem Description Princess Alisha invites her friends to come to her birthday party. Each of her f ...

  4. php函数应用场景

    截取文件后缀: $slen = strlen($suffix); substr($this->uri_string, -$slen) === $suffix 原理:截取倒数多少长度字符 判断多维 ...

  5. Mysql大小写敏感的问题 --转

    一.1 CREATE TABLE NAME(name VARCHAR(10)); 对这个表,缺省情况下,下面两个查询的结果是一样的: SELECT * FROM TABLE NAME WHERE na ...

  6. servlet tomcat eclipse

    网上搜到的很多利用eclipse结合tomcat开发servlet的教程都要修改server.xml 感觉这种方式太粗暴了,server.xml最好是与应用无关的, 这里比较推荐export war的 ...

  7. Linux学习之Shell编程基础

    转自:http://my.oschina.net/itblog/blog/204410 1 语法基本介绍1.1 开头 程序必须以下面的行开始(必须方在文件的第一行): #!/bin/sh 符号#!用来 ...

  8. 前端编程提高之旅(六)----backbone实现todoMVC

                乐帝当年学习backbone时.最開始是看官网todoMVC的实现.后来了解到requireJS便于管理JS代码.就对官网代码做了requireJS管理.但此时乐帝感觉此时的t ...

  9. python3 与 python2的 区别比较

    http://sebug.net/paper/books/dive-into-python3/porting-code-to-python-3-with-2to3.html

  10. 剪格子|2013年蓝桥杯A组题解析第九题-fishers

    剪格子 如图p1.jpg所示,3 x 3 的格子中填写了一些整数. 我们沿着图中的红色线剪开,得到两个部分,每个部分的数字和都是60. 本题的要求就是请你编程判定:对给定的m x n 的格子中的整数, ...