HihoCoder - 1403 后缀数组一·重复旋律

描述

小Hi平时的一大兴趣爱好就是演奏钢琴。我们知道一个音乐旋律被表示为长度为 N 的数构成的数列。

小Hi在练习过很多曲子以后发现很多作品自身包含一样的旋律。旋律是一段连续的数列,相似的旋律在原数列可重叠。比如在1 2 3 2 3 2 1 中 2 3 2 出现了两次。

小Hi想知道一段旋律中出现次数至少为K次的旋律最长是多少?

输入

第一行两个整数 N和K。1≤N≤20000 1≤K≤N

接下来有 N 个整数,表示每个音的数字。1≤数字≤100

输出

一行一个整数,表示答案。

Sample Input

8 2
1
2
3
2
3
2
3
1

Sample Output

4

总结:打算把后缀数组复习一遍本题很明显求的是连续k个height数组的最小值当中的最大值,然后有两种做法二分或单调队列这里用的是单调队列
#include <bits/stdc++.h>

using namespace std;
const int maxn = 200005;
int n, K, rk[maxn], sa[maxn], y[maxn], ln, p, m, c[maxn];
int H[maxn], wr[maxn], q[maxn], l, r, a[maxn], pos[maxn], k;

bool cmp(int k1, int k2, int ls) {
	return wr[k1] == wr[k2] && wr[k1 + ls] == wr[k2 + ls];
}
void SA(int x) {
	m = x;
	for (int i = 1; i <= n; ++i) c[rk[i]]++;
	for (int i = 1; i <= m; ++i) c[i] += c[i - 1];
	for (int i = n; i >= 1; --i) sa[c[rk[i]]--] = i;
	ln = 1, p = 0;
	while(p < n) {
		k = 0;
		for (int i = n - ln + 1; i <= n; ++i) y[++k] = i;
		for (int i = 1; i <= n; ++i) if(sa[i] > ln) y[++k] = sa[i] - ln;
		memset(c, 0, sizeof c);
		for (int i = 1; i <= n; ++i) wr[i] = rk[i];
		for (int i = 1; i <= n; ++i) c[wr[y[i]]]++;
		for (int i = 1; i <= m; ++i) c[i] += c[i - 1];
		for (int i = n; i >= 1; --i) sa[c[wr[y[i]]]--] = y[i];
		for (int i = 1; i <= n; ++i) wr[i] = rk[i];
		rk[sa[1]] = 1; p = 1;
		for (int i = 2; i <= n; ++i) {
			if(!cmp(sa[i], sa[i - 1], ln)) ++p;
			rk[sa[i]] = p;
		}
	} ln <<= 1; m = p;
}
void Gh() {
	k = 0;
	for (int i = 1; i <= n; ++i) rk[sa[i]] = i;
	for (int i = 1; i <= n; ++i) {
		if(k) --k; int j = sa[rk[i] - 1];
		while(a[i + k] == a[j + k]) ++k;
		H[rk[i]] = k;
	}
}
int main() {
	scanf("%d%d", &n, &K);
	for (int i = 1; i <= n; ++i) scanf("%d", &rk[i]), a[i] = rk[i];
	SA(105); Gh(); int ans = 0;
	for (int i = 1; i <= n; ++i) {
		while(l < r && H[i] < q[r]) r--;
		q[++r] = H[i]; pos[r] = i;
		while(l < r && pos[l] <= i - K + 1) ++l;
		if(i >= K) ans = max(ans, q[l]);
	} printf("%d\n", ans);
	for (int i = 1; i <= n; ++i) cout << H[i] << " ";
	return 0;
}

  

 

原文地址:https://www.cnblogs.com/oi-forever/p/9153095.html

时间: 2024-11-07 02:05:45

HihoCoder - 1403 后缀数组一·重复旋律的相关文章

2017.3.4[hihocoder#1403]后缀数组一&#183;重复旋律

好久没发博了. 后缀数组板子题.具体实现就不解释了,hihocoder很良心. http://hihocoder.com/problemset/problem/1403 1 #include<cmath> 2 #include<queue> 3 #include<cstdio> 4 #include<vector> 5 #include<cstdlib> 6 #include<cstring> 7 #include<iostre

hihocoder #1407 : 后缀数组二&#183;重复旋律2

#1407 : 后缀数组二·重复旋律2 Time Limit:5000ms Case Time Limit:1000ms Memory Limit:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列.小Hi在练习过很多曲子以后发现很多作品自身包含一样的旋律. 旋律可以表示为一段连续的数列,相似的旋律在原数列不可重叠,比如在1 2 3 2 3 2 1 中 2 3 2 出现了一次,2 3 出现了两次,小Hi想知道一段旋律中出现次数至少为两次

hihocoder #1415 : 后缀数组三&#183;重复旋律3

#1415 : 后缀数组三·重复旋律3 Time Limit:5000ms Case Time Limit:1000ms Memory Limit:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列.小Hi在练习过很多曲子以后发现很多作品中的旋律有共同的部分. 旋律是一段连续的数列,如果同一段旋律在作品A和作品B中同时出现过,这段旋律就是A和B共同的部分,比如在abab 在 bababab 和 cabacababc 中都出现过.小Hi想

后缀数组四&#183;重复旋律4

后缀数组四·重复旋律4 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列.小Hi在练习过很多曲子以后发现很多作品中的旋律有重复的部分. 我们把一段旋律称为(k,l)-重复的,如果它满足由一个长度为l的字符串重复了k次组成. 如旋律abaabaabaaba是(4,3)重复的,因为它由aba重复4次组成. 小Hi想知道一部作品中k最大的(k,l)-重复旋律. 解题方法提示 输入 一

hiho一下123周 后缀数组四&#183;重复旋律

后缀数组四·重复旋律4 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列.小Hi在练习过很多曲子以后发现很多作品中的旋律有重复的部分. 我们把一段旋律称为(k,l)-重复的,如果它满足由一个长度为l的字符串重复了k次组成. 如旋律abaabaabaaba是(4,3)重复的,因为它由aba重复4次组成. 小Hi想知道一部作品中k最大的(k,l)-重复旋律. 解题方法提示 输入 一

hiho一下122周 后缀数组三&#183;重复旋律

后缀数组三·重复旋律3 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列.小Hi在练习过很多曲子以后发现很多作品中的旋律有共同的部分. 旋律是一段连续的数列,如果同一段旋律在作品A和作品B中同时出现过,这段旋律就是A和B共同的部分,比如在abab 在 bababab 和 cabacababc 中都出现过.小Hi想知道两部作品的共同旋律最长是多少? 解题方法提示 输入 共两行.一

后缀数组二&#183;重复旋律2

后缀数组二·重复旋律2 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列.小Hi在练习过很多曲子以后发现很多作品自身包含一样的旋律. 旋律可以表示为一段连续的数列,相似的旋律在原数列不可重叠,比如在1 2 3 2 3 2 1 中 2 3 2 出现了一次,2 3 出现了两次,小Hi想知道一段旋律中出现次数至少为两次的旋律最长是多少? 解题方法提示 输入 第一行一个整数 N.1≤

hiho一下121周 后缀数组二&#183;重复旋律2

后缀数组二·重复旋律2 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列.小Hi在练习过很多曲子以后发现很多作品自身包含一样的旋律. 旋律可以表示为一段连续的数列,相似的旋律在原数列不可重叠,比如在1 2 3 2 3 2 1 中 2 3 2 出现了一次,2 3 出现了两次,小Hi想知道一段旋律中出现次数至少为两次的旋律最长是多少? 解题方法提示 输入 第一行一个整数 N.1≤N

hiho一下120周 后缀数组一&#183;重复旋律

后缀数组一·重复旋律 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列. 小Hi在练习过很多曲子以后发现很多作品自身包含一样的旋律.旋律是一段连续的数列,相似的旋律在原数列可重叠.比如在1 2 3 2 3 2 1 中 2 3 2 出现了两次. 小Hi想知道一段旋律中出现次数至少为K次的旋律最长是多少? 解题方法提示 输入 第一行两个整数 N和K.1≤N≤20000 1≤K≤N