PKU 3261 Milk Patterns

  • 最長部分繰り返し文字列という問題だと思います
  • Spaghetti Sourceのライブラリをお借りしました
#define SETNUM(rank, i,s) \
	NUM[i] = make_pair(make_pair(rank[i], i+s<n?rank[i+s]:n), i);
#define RENUMBER(rank) \
	sort(NUM.begin(), NUM.begin()+n); \
	rank[ NUM[0].second ] = 0; \
	for (int i = 1; i < n; ++i) \
	rank[ NUM[i].second ] = rank[ NUM[i-1].second ] \
	+ (NUM[i-1].first != NUM[i].first) ;

int ranks[32][200000];
void karp_miller_rosenberg_pre(const vector<int>& text) {
	const int n = text.size();
	int m = 0;
	vector<pair<pair<int,int>,int> > NUM(n);
	copy(text.begin(), text.begin()+n, ranks[m]);
	for (int k = 0; k <= n; k ? k*=2 : ++k) { // power of 2
		for (int i = 0; i < n; ++i) SETNUM(ranks[m], i, k);
		if (k > 0) ++m; RENUMBER(ranks[m]);
	}
}
int repeated_factor(const vector<int>& text, int r, int k) {
	const int n = text.size();
	int t, s;
	vector<pair<pair<int,int>,int> > NUM(n);
	vector<int> rank(n);
	for (s = 1, t = 0; s * 2 < r; s *= 2, ++t);
	for (int i = 0; i < n; ++i) SETNUM(ranks[t], i, r-s);
	RENUMBER(rank);
	vector<int> count(n);
	for (int i = 0; i < n; ++i)
		if (++count[ rank[i] ] >= k) return i;
	return -1;
}
vector<int> longest_repeated_factor(const vector<int>& text, int k) {
	karp_miller_rosenberg_pre(text);
	int low = 1, high = text.size();
	while (low+1 < high) {
		int mid = (low + high) / 2;
		if (repeated_factor(text, mid, k) < 0) high = mid;
		else                                    low = mid;
	}
	int t = repeated_factor(text, low, k);
	return t >= 0 ? vector<int>(text.begin()+t, text.begin()+t+low) : vector<int>();
}

int main()
{
	int N, K;
	cin >> N >> K;
	vector<int> text;
	for (int i = 0; i < N; ++i) {
		int in;
		cin >> in;
		text.push_back(in);
	}

	const vector<int> answer = longest_repeated_factor(text, K);
	//for (vector<int>::const_iterator it = answer.begin(); it != answer.end(); ++it) {
	//	cout << *it << " ";
	//}
	//cout << endl;
	cout << answer.size() << endl;
}

Spaghetti Source - 最長繰り返し部分文字列 (Karp Miller Rosenberg) - http://www.prefield.com/algorithm/string/karp_miller_rosenberg.html