首页 > 其他分享 >POJ 1743 Musical Theme

POJ 1743 Musical Theme

时间:2022-11-09 18:35:26浏览次数:37  
标签:int rep -- Theme POJ sa include Musical rk


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

后缀数组+二分

#include<iostream>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int Min = 0;
const int Max = 0x7FFFFFFF;
const int maxn = 20005;
const int bit = 256;
class suffix
{
private:
int s[maxn];
int r[maxn], w[maxn], ss[maxn], h[maxn];
int sa[maxn], rk[maxn + maxn], size;
int size1;
public:
bool get(){
if (scanf("%d", &size) != 1 || size == 0)return false;
for (int i = 1; i <= size; i++) scanf("%d", &s[i]);
for (int i = 1; i <= size; i++) s[i] = s[i + 1] - s[i] + 88;
s[size] = 0;
return true;
}
void pre()
{
memset(rk, 0, sizeof(rk));
for (int i = 1; i <= bit; i++) w[i] = 0;
for (int i = 1; i <= size; i++) w[(int)s[i]]++;
for (int i = 1; i <= bit; i++) w[i] += w[i - 1];
for (int i = size; i; i--) sa[w[(int)s[i]]--] = i;
for (int i = 1, j = 1; i <= size; i++)
rk[sa[i]] = (s[sa[i]] == s[sa[i + 1]] ? j : j++);
for (int j = 1; j < size; j += j)
{
for (int i = 1; i <= size; i++) w[i] = 0;
for (int i = 1; i <= size; i++) w[rk[i + j]]++;
for (int i = 1; i <= size; i++) w[i] += w[i - 1];
for (int i = size; i; i--) ss[w[rk[i + j]]--] = i;

for (int i = 1; i <= size; i++) w[i] = 0;
for (int i = 1; i <= size; i++) w[rk[ss[i]]]++;
for (int i = 1; i <= size; i++) w[i] += w[i - 1];
for (int i = size; i; i--) sa[w[rk[ss[i]]]--] = ss[i];

for (int i = 1, k = 1; i <= size; i++)
r[sa[i]] = (rk[sa[i]] == rk[sa[i + 1]] && rk[sa[i] + j] == rk[sa[i + 1] + j]) ? k : k++;
for (int i = 1; i <= size; i++) rk[i] = r[i];
}
for (int i = 1, k = 0, j; i <= size; h[rk[i++]] = k)
for (k ? k-- : 0, j = sa[rk[i] - 1]; s[i + k] == s[j + k]; k++);
}
void work()
{
int mid, l = 0, r = size >> 1;
for (mid = (l + r) >> 1; l < r;)
{
int minx = Max, maxx = Min, f = 0;
for (int i = 2; i <= size; i++)
{
if (h[i] < mid)
{
minx = Max;
maxx = Min;
}
else
{
minx = min(minx, min(sa[i], sa[i - 1]));
maxx = max(maxx, max(sa[i], sa[i - 1]));
if (maxx - minx >= mid)
{
f = 1;
break;
}
}
}
if (f) l = mid; else r = mid - 1;
mid = (l + r) >> 1;
if (l + 1 == r) mid++;
}
if (mid >= 4) printf("%d\n", mid + 1);
else puts("0");
}
}f;

int main()
{
while (f.get())
{
f.pre();
f.work();
}
return 0;
}


最近重新回顾了一遍写了新的板子。



#include<set>
#include<map>
#include<ctime>
#include<cmath>
#include<stack>
#include<queue>
#include<bitset>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#define rep(i,j,k) for (int i = j; i <= k; i++)
#define per(i,j,k) for (int i = j; i >= k; i--)
#define lson x << 1, l, mid
#define rson x << 1 | 1, mid + 1, r
using namespace std;
typedef long long LL;
const int low(int x) { return x&-x; }
const double eps = 1e-8;
const int INF = 0x7FFFFFFF;
const int mod = 1e9 + 7;
const int N = 2e4 + 10;
int T, n, s[N];

struct Sa
{
//char s[N];
int rk[2][N], sa[N], h[N], w[N], now;
int rmq[N][20], lg[N];

void GetS()
{
//scanf("%s", s + 1);
getchar();
//gets(s + 1);
//gets_s(s + 1, N);
}

void getsa(int z, int &m)
{
int x = now, y = now ^= 1;
rep(i, 1, z) rk[y][i] = n - i + 1;
for (int i = 1, j = z; i <= n; i++)
if (sa[i] > z) rk[y][++j] = sa[i] - z;

rep(i, 1, m) w[i] = 0;
rep(i, 1, n) w[rk[x][rk[y][i]]]++;
rep(i, 1, m) w[i] += w[i - 1];
per(i, n, 1) sa[w[rk[x][rk[y][i]]]--] = rk[y][i];
for (int i = m = 1; i <= n; i++)
{
int *a = rk[x] + sa[i], *b = rk[x] + sa[i - 1];
rk[y][sa[i]] = *a == *b&&*(a + z) == *(b + z) ? m - 1 : m++;
}
}

void getsa(int m)
{
now = 0; //n = strlen(s + 1);
rep(i, 1, m) w[i] = 0;
rep(i, 1, n) w[s[i]]++;
rep(i, 1, m) rk[1][i] = rk[1][i - 1] + (bool)w[i];
rep(i, 1, m) w[i] += w[i - 1];
rep(i, 1, n) rk[0][i] = rk[1][s[i]];
rep(i, 1, n) sa[w[s[i]]--] = i;
for (int x = 1, y = rk[1][m]; x <= n && y <= n; x <<= 1) getsa(x, y);
for (int i = 1, j = 0; i <= n; h[rk[now][i++]] = j ? j-- : 0)
while (s[sa[rk[now][i] - 1] + j] == s[i + j]) ++j;
}

void getrmq()
{
lg[1] = 0;
rep(i, 2, n) rmq[i][0] = h[i], lg[i] = lg[i >> 1] + 1;
for (int i = 1; (1 << i) <= n; i++)
{
rep(j, 2, n)
{
if (j + (1 << i) > n + 1) break;
rmq[j][i] = min(rmq[j][i - 1], rmq[j + (1 << i - 1)][i - 1]);
}
}
}

int lcp(int x, int y)
{
int l = min(rk[now][x], rk[now][y]) + 1, r = max(rk[now][x], rk[now][y]);
return min(rmq[l][lg[r - l + 1]], rmq[r - (1 << lg[r - l + 1]) + 1][lg[r - l + 1]]);
}
bool check(int x)
{
int l = sa[1], r = sa[1];
for (int i = 1; i < n; i++)
{
if (h[i + 1] >= x) l = min(l, sa[i + 1]), r = max(r, sa[i + 1]);
else
{
if (r - l >= x) return true;
l = r = sa[i + 1];
}
}
return r - l >= x;
}
void work()
{
int l = 4, r = n / 2;
while (l <= r)
{
if (check(l + r >> 1)) l = (l + r >> 1) + 1;
else r = (l + r >> 1) - 1;
}
printf("%d\n", l > 4 ? l : 0);
}
}sa;

int main()
{
while (scanf("%d", &n), n)
{
rep(i, 1, n) scanf("%d", &s[i]);
--n;
rep(i, 1, n) s[i] = s[i + 1] - s[i] + 88;
sa.getsa(200);
sa.work();
}
return 0;
}





标签:int,rep,--,Theme,POJ,sa,include,Musical,rk
From: https://blog.51cto.com/u_15870896/5837720

相关文章

  • 究竟什么是POJO?
    POJO(PlainOldJavaObject)这种叫法是MartinFowler、RebeccaParsons和JoshMacKenzie在2000年的一次演讲的时候提出来的。     我在做J2EE培训中发现我的......
  • POJ3061 Subsequence
    思路:尺取法注意本题目中所有的内容全部是证书,这就为我们维护了一个很好的单调性.考虑最暴力的\(\mathcalO(n^3)\)的做法,就是枚举起点,终点,然后分别求和.但是......
  • POJ-1018
    POJ-1018(现在好像过不了)题意目前有一个公司需要购进宽带设备,每种设备有多款机器供选择,每种设备都需购进一台,现给出每台设备的带宽p与价格q,要求选择设备的最小带宽\(min(......
  • POJ-3737
    POJ-3737题意给出一个圆锥的表面积,求最大体积。思路显然,得到底面积的半径后,一切都能得到。在我们慢慢延长半径时,发现不满足线性,而是单峰函数。故三分。圆锥复习Code......
  • poj 2392 Space Elevator
    给出了一些砖块,砖块有高度,最高可以达到的高度(高度限制)和数量,问可以用这些砖块堆的最大高度   f[i][j]考虑前i块,能否堆出高度为j   f[i][j]|=f[i-1][j-k*h[i]......
  • 【POJ1430】Binary Stirling Numbers(第二类斯特林数,组合数)
    求\(\begin{Bmatrix}n\\m\end{Bmatrix}\bmod2\)的值。由第二类斯特林数的递推公式:\[\begin{Bmatrix}n\\m\end{Bmatrix}=\begin{Bmatrix}n-1\\m-1\end{Bmatrix}+m\begi......
  • 【poj1061】青蛙的约会(扩展欧几里得)
    不妨设青蛙A的出发点坐标是\(m1\),青蛙B的出发点坐标是\(n1\)。青蛙A一次能跳\(m\)米,青蛙B一次能跳\(n\)米,跳一圈长\(l\)米,设青蛙A、B跳了\(x\)次。那么题目要求的是满足下......
  • 【C语言语法】 POJ上奇奇怪怪的Compile error
    【C语言语法】POJ上奇奇怪怪的Compileerror收集中,因为老在\(POJ\)上莫名奇妙地\(CE\),所以记录一下出现过的错误1.不能用万能头文件<bits/stdc++.h>懒癌克星2.不支......
  • DAO,DTO,DO,VO,AO,BO,POJO,PO,Entity,Model,View的概念
    DAO(DataAccessObject)数据访问对象DTO(DataTransferObject)数据传输对象DO(DomainObject)领域对象VO(ViewObject)视图模型AO(ApplicationObject)应用对象BO(Business......
  • 关于PO、BO、VO、DTO、DAO、POJO等概念的理解
    PO(PersistantObject)持久对象PO是持久化对象,用于表示数据库中的一条记录映射成的Java对象,类中应该都是基本数据类型和String,而不是更复杂的类型,因为要和数据库表字段对应......