POJ 3261 USACO 2006 December Gold Milk Patterns

题目大意:给出一个字符串,求出出现过k次以上的最长的子串(可重叠).

思路:现弄出来sa数组和height数组,之后就是判断每个长度为k的height数组的区间中最小的数字的最大值了.为什么好多人都二分了?这只要单调队列扫一次就行了啊..

CODE:

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 1000010
using namespace std;

int len,k;
int s[MAX],val[MAX],sa[MAX];
int rank[MAX],height[MAX];

inline bool Same(int x,int y,int l)
{
	return val[x] == val[y] &&
	((x + l >= len && y + l >= len) || (x + l < len && y + l < len && val[x + l] == val[y + l]));
}

void GetSuffixArray()
{
	static int _val[MAX],cnt[MAX],q[MAX],lim = 1000001;
	for(int i = 0; i < len; ++i)	++cnt[val[i] = s[i]];
	for(int i = 1; i < lim; ++i)	cnt[i] += cnt[i - 1];
	for(int i = len - 1; ~i; --i)	sa[--cnt[val[i]]] = i;
	for(int d = 1;; ++d) {
		int top = 0,l = 1 << (d - 1);
		for(int i = 0; i < len; ++i)	if(sa[i] + l >= len)	q[top++] = sa[i];
		for(int i = 0; i < len; ++i)	if(sa[i] >= l)	q[top++] = sa[i] - l;

		for(int i = 0; i < lim; ++i)	cnt[i] = 0;
		for(int i = 0; i < len; ++i)	++cnt[val[q[i]]];
		for(int i = 1; i < len; ++i)	cnt[i] += cnt[i - 1];
		for(int i = len - 1; ~i; --i)	sa[--cnt[val[q[i]]]] = q[i];
		lim = 0;
		for(int i = 0,j; i < len; ++lim) {
			for(j = i; j < len - 1 && Same(sa[j],sa[j + 1],l); ++j);
			for(; i <= j; ++i)	_val[sa[i]] = lim;
		}
		for(int i = 0; i < len; ++i)	val[i] = _val[i];
		if(lim == len)	break;
	}
	return ;
}

void GetHeight()
{
	for(int i = 0; i < len; ++i)	rank[sa[i]] = i;
	for(int k = 0,i = 0; i < len; ++i) {
		if(k)	--k;
		int j = sa[rank[i] - 1];
		while(s[i + k] == s[j + k])	++k;
		height[rank[i]] = k;
	}
}

struct Complex{
	int pos,val;

	Complex(int _,int __):pos(_),val(__) {}
	Complex() {}
};

int main()
{
	cin >> len >> k;
	for(int i = 0; i < len; ++i)
		scanf("%d",&s[i]);
	GetSuffixArray();
	GetHeight();
	deque<Complex> q;
	int ans = 0;
	for(int i = 0; i < len; ++i) {
		while(!q.empty() && height[i] <= q.back().val)	q.pop_back();
		while(!q.empty() && i - q.front().pos >= k - 1)		q.pop_front();
		q.push_back(Complex(i,height[i]));
		ans = max(ans,q.front().val);
	}
	cout << ans << endl;
	return 0;
}
时间: 2024-08-01 04:12:06

POJ 3261 USACO 2006 December Gold Milk Patterns的相关文章

[Poj3261] [Bzoj1717] [后缀数组论文例题,USACO 2006 December Gold] Milk Patterns [后缀数组可重叠的k次最长重复子串]

和上一题(POJ1743,上一篇博客)相似,只是二分的判断条件是:是否存在一段后缀的个数不小于k 1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <cstring> 6 #include <cmath> 7 #include <ctime> 8 #include <map&

USACO 2006 November Gold

POJ 3253 Fence Repair STL堆操作 我想说,STL里堆是我目前见到最蛋疼的操作. #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cstdlib> #include <cmath> #include <utility> #include <vector> #inc

POJ 3261 Milk Patterns

Milk Patterns Time Limit: 5000ms Memory Limit: 65536KB This problem will be judged on PKU. Original ID: 326164-bit integer IO format: %lld      Java class name: Main Farmer John has noticed that the quality of milk given by his cows varies from day t

POJ 题目3261 Milk Patterns(后缀数组求最长重叠至少k次的子串长度)

Milk Patterns Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 12128   Accepted: 5387 Case Time Limit: 2000MS Description Farmer John has noticed that the quality of milk given by his cows varies from day to day. On further investigation,

POJ 3261 Milk Patterns sa+二分

Milk Patterns Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 11944   Accepted: 5302 Case Time Limit: 2000MS Description Farmer John has noticed that the quality of milk given by his cows varies from day to day. On further investigation,

poj3261 Milk Patterns(后缀数组)

Milk Patterns Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 12571 Accepted: 5572 Case Time Limit: 2000MS Description Farmer John has noticed that the quality of milk given by his cows varies from day to day. On further investigation, he

poj 3261 Milk Patterns 后缀数组+二分

1 /*********************************************************** 2 题目: Milk Patterns(poj 3261) 3 链接: http://poj.org/problem?id=3261 4 题意: 给一串数字,求这些数字中公共子串个数大于k的 5 最长串. 6 算法: 后缀数组+二分 7 ***********************************************************/ 8 #incl

POJ 3261 Milk Patterns (求可重叠的k次最长重复子串)

Milk Patterns Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 14094   Accepted: 6244 Case Time Limit: 2000MS Description Farmer John has noticed that the quality of milk given by his cows varies from day to day. On further investigation,

POJ 3261 Milk Patterns 可重复k次的最长重复子串

Milk PatternsTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?id=3261 Description Farmer John has noticed that the quality of milk given by his cows varies from day to day. On further investigation, he discovered that although he c