A musical melody is represented as a sequence of N (1<=n<=20000) Notes this is integers in the range 1..88, each rep Resenting a key on the piano. It is unfortunate, but true, this representation of melodies ignores the notion of musical timing; But, the this programming task was about notes and not timings.
Many composers structure their music around a repeating &qout; Theme &qout, which, being a subsequence of an entire melody, are 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 their other appearance (s)
Transposed means that a constant positive or negative value are added to every note value in the theme subsequence.
Given a melody, compute the length (number of notes) of the longest theme.
Give you a piece of music, the movement is composed of n notes, these notes by 1. An integer representation of 88. Now you need to find the longest melody so that the melody has at least 5 notes, at least two times, and this two times the position does not intersect (if the two melodies are the same after the same tone, then the two melodies can be seen as appearing two times).
The input contains multiple sets of data, and the first row of each group of data includes an integer n, representing the length of the movement. The next line consists of n integers representing each note.
Outputs an integer that represents the length of the longest melody that satisfies the test instructions.
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
5
Said... String of real ghost animals. Half-day% end of Ro " suffix array-a powerful tool to deal with strings ", completely roll the thick (KMP, heart forever Pain).
First finished the uoj#35 template problem, and adjusted for half a day, the heart is collapsed.
So I started the problem of LG.
A template problem with a suffix automaton. Construct a new string with the difference between two adjacent numbers, use the suffix array for the new string LG, and then two minutes to find the maximum length of the disjoint substring.
Pay attention to the situation of the n=1 (can be sentenced with the n<10 situation).
1#include <cstdio>2#include <cstring>3#include <algorithm>4 using namespacestd;5 Const intMAXN =20005;6 intS[MAXN], SX[MAXN], SY[MAXN], SSUM[MAXN], SA[MAXN], RK[MAXN], H[MAXN];7InlineBOOLcmpint* Y,intIintJintk) {8 returnY[i] = = Y[j] && y[i + K] = = Y[j +K];9 }Ten One voidGetsa (intNintm) { A intI, J, p, *x = SX, *y =Sy; - for(i =0; I < m; ++i) Ssum[i] =0; - for(i =0; I < n; ++i) ++ssum[x[i] =S[i]]; the for(i =1; I < m; ++i) Ssum[i] + = ssum[i-1]; - for(i = n-1; ~i; -i) sa[--ssum[x[i]] =i; - for(p = j =1; P < n; J <<=1, M =p) { - for(P =0, i = n-j; I < n; ++i) y[p++] =i; + for(i =0; I < n; ++i)if(Sa[i] >= j) y[p++] = Sa[i]-J; - for(i =0; I < m; ++i) Ssum[i] =0; + for(i =0; I < n; ++i) + +Ssum[x[y[i]]; A for(i =1; I < m; ++i) Ssum[i] + = ssum[i-1]; at for(i = n-1; ~i; -i) sa[--ssum[x[y[i] []] =Y[i]; -Swap (x, y); x[sa[0]] =0; - for(p = i =1; I < n; ++i) X[sa[i] = cmp (y, Sa[i-1], Sa[i], j)? P-1: p++; - } - } - in voidGeth (intN) { - intJ, k =0; to for(inti =1; I <= N; ++i) Rk[sa[i] =i; + for(inti =0; I < n; h[rk[i++]] =k) - for(K. k--:0, j = Sa[rk[i]-1]; S[i + K] = = S[j + K]; ++k); the } * $ intSolveintXintN) {Panax Notoginseng inti =2, Minh, Maxh; - while(1) { the while(I <= n && h[i] < x) + +i; + if(i > N) Break; AMaxh = Minh = Sa[i-1]; the while(I <= n && h[i] >=x) { +Minh = Min (Minh, sa[i]); MAXH = Max (Maxh, sa[i++]); - } $ if(Maxh-minh > x)return true; $ } - return false; - } the - intMain () {Wuyi intN; the while(~SCANF ("%d", &n) &&N) { -memset (SX,0,sizeof(SX)); Wumemset (SY,0,sizeof(SY)); -memset (SX,0,sizeof(SA)); Aboutmemset (Ssum,0,sizeof(Ssum)); $ for(inti =0; I < n; ++i) scanf ("%d", S +i); - if(--n <9) {puts ("0");Continue; } - for(inti =0; I < n; ++i) S[i] = S[i +1]-S[i] + -; -S[n] =0; AGetsa (n +1, $); Geth (n); + intL =1, r = (n >>1) +1; the while(L < R-1) { - intMID = L + R >>1; $ if(Solve (Mid, n)) L =mid; the ElseR =mid; the } theprintf"%d\n", L <4?0: R); the } - return 0; in}
(the variable name in the paper is so strange)
Sorry blog late, should be able to update on time.
[POJ1743] Musical Theme (suffix array)