Cod sursa(job #757916)

Utilizator MciprianMMciprianM MciprianM Data 13 iunie 2012 19:16:13
Problema Substr Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.96 kb
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <ctime>
#include <cstdlib>
#include <cstring>

using namespace std;

int prime;
int tenp [17000];
int *mp;

bool prim (int x) {
	if (x < 2) {
		return false;
	}
	if (x == 2) {
		return true;
	}
	if (x % 2 == 0) {
		return false;
	}
	for (int d = 3; d * d <= x; d += 2) {
		if (x % d == 0) {
			return false;
		}
	}
	return true;
}

void init () {
	srand (time (NULL));
	int i, f = rand () % 10;
	int cate = 10 + ('z' - 'a') * 2;
	prime = 100000 + f * ((unsigned)rand () % 10000);
	if (prime % 2 == 0) {
		++ prime;
	}
	while (! prim (prime)) {
		prime += 2;
	}
	tenp [0] = 1 % prime;
	for (i = 1; i < 17000; ++ i) {
		tenp [i] = (tenp [i - 1] * cate) % prime;
	}
	mp = (int *)malloc (sizeof (int) * (prime + 9));
}

inline int charToCif (char c) {
	if ('0' <= c && c <= '9') {
		return c - '0';
	}
	if ('a' <= c && c <= 'z') {
		return c - 'a' + 10;
	}
	if ('A' <= c && c <= 'Z') {
		return c - '0' + 11 + 'z' - 'a';
	}
}

bool has (string &s, int l, int k) {
	int sz = s.size ();
	memset (mp, 0, sizeof (int) * (prime + 9));
	int cate = 10 + ('z' - 'a') * 2;
	int i, hash = 0, j;
	for (i = 0; i < l; ++ i) {
		hash = (hash * cate + charToCif (s [i])) % prime;
	}
	mp [hash] = 1;
	for (i = l, j = 0; i < sz; ++ i, ++ j) {
		hash = (hash - ((tenp [l - 1] * charToCif (s [j])) % prime)) % prime;
		if (hash < 0) {
			hash += prime;
		}
		hash = (hash * cate + charToCif (s [i])) % prime;
		++ mp [hash];
	}
	for (i = 0; i < prime; ++ i) {
		if (mp [i] >= k) {
			return true;
		}
	}
	return false;
}

int main () {
	init ();
	int i, n, k, pas;
	string s;
	ifstream f ("substr.in");
	ofstream g ("substr.out");
	f >> n >> k;
	f >> s;
	for (i = 0, pas = (1 << 15); pas; pas >>= 1) {
		if (i + pas <= n && has (s, i + pas, k)) {
			i += pas;
		}
	}
	g << i << endl;
	f.close ();
	g.close ();
	return 0;
}