Cod sursa(job #1072222)

Utilizator antonioteoZait Teodor Antonio antonioteo Data 4 ianuarie 2014 10:55:04
Problema Substr Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.59 kb
#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
using namespace std;

ifstream fin("substr.in");
ofstream fout("substr.out");

#define nmax 16394
#define m1 2000003
#define m2 666013
#define b1 257
#define b2 259

int i, n, k;
int cnt;

char a[nmax];

int h1, h2;
int pw1[nmax], pw2[nmax];

struct nod {
	int x;
	int l;
	int ap;
	nod(){};
	nod(int _x, int _l, int _ap){x = _x; l = _l; ap = _ap;};
};
vector <nod> H1[m1 + 3];
vector <nod> H2[m2 + 3];

inline bool Search(vector <nod> H[], int h, int lg, int &t){
	vector <nod> :: iterator it;
	for (it = H[h].begin(); it != H[h].end(); ++it) {
		if (it->x == h && it->l == lg) {
			++it->ap;
			t = it->ap;
			return 1;
		}
	}
	return 0;
}

inline bool Found(int L) {
	int j, times1 = 0, times2 = 0;
	h1 = h2 = 0;
	for (j = 1; j <= n; ++j) {
		h1 = (h1 * b1 + a[j]) % m1;
		h2 = (h2 * b2 + a[j]) % m2;
		if (j < L) continue;
		if (!Search(H1, h1, L, times1)) 
			H1[h1].push_back(nod(h1, L, 1));
		if (!Search(H2, h2, L, times2))
			H2[h2].push_back(nod(h2, L, 1));
		if (min(times1, times2) >= k)
			return 1;
		h1 = ((h1 - (pw1[L - 1] * a[j - L + 1])) % m1 + m1) % m1;
		h2 = ((h2 - (pw2[L - 1] * a[j - L + 1])) % m2 + m2) % m2;
	}
	return 0;
}

int main() {
	fin >> n >> k;
	fin >> (a + 1);
	for (cnt = 1; cnt <= n; cnt <<= 1);
	pw1[0] = pw2[0] = 1;
	for (i = 1; i <= n; ++i) {
		pw1[i] = (pw1[i - 1] * b1) % m1;
		pw2[i] = (pw2[i - 1] * b2) % m2;
	}
	for (i = 0; cnt; cnt >>= 1) {
		if (i + cnt <= n && Found(i + cnt))
			i += cnt;
	}
	fout << i << '\n';
	return 0;
}