Cod sursa(job #514292)

Utilizator ciprianfFarcasanu Alexandru Ciprian ciprianf Data 18 decembrie 2010 13:27:33
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.54 kb
#include <stdio.h>
#include <vector>
using namespace std;
#define FOR(i, v) for(vector< pair <int, int> > ::iterator i = v.begin(); i != v.end(); ++i)
#define mp make_pair
#define NMAX 17000
const int MOD1 = 100007;
const int MOD2 = 100013;
const int SIGMA = 127;
vector <pair <int, int> > G[MOD1];
int n, k, cnt = 1;
char S[NMAX];
void add(int x, int y){
	FOR(i, G[x])
		if(i->first == y){
			i->second ++;
			if(i->second > cnt) cnt = i->second;
			return ;
		}
	G[x].push_back(mp(y,1));
}
int valid(int L){
	int hash1 = 0, hash2 = 0;
	int put1 = 1, put2 = 1;
	cnt = 1;
	for(int i = 1; i <= L; ++i){
		hash1 = (hash1 * SIGMA + S[i])%MOD1;
		hash2 = (hash2 * SIGMA + S[i])%MOD2;
		if(i == 1) continue;
		put1 = (put1*SIGMA)%MOD1;
		put2 = (put2*SIGMA)%MOD2;
	}
	int ha = hash1;
	add(hash1, hash2);
	for(int i = L+1; i <= n; ++i){
		hash1 = (((hash1 - ((S[i-L]*put1)%MOD1) +MOD1)%MOD1) * SIGMA + S[i])%MOD1;
		hash2 = (((hash2 - ((S[i-L]*put2)%MOD2) +MOD2)%MOD2) * SIGMA + S[i])%MOD2;
		add(hash1, hash2);
	}
	G[ha].clear();
	for(int i = L+1; i <= n; ++i){
		ha = (((ha - ((S[i-L]*put1)%MOD1) +MOD1)%MOD1) * SIGMA + S[i])%MOD1;
		G[ha].clear();
	}
	if(cnt >= k) return 1;
	return 0;
}
int main(){
	freopen("substr.in", "r", stdin);
	freopen("substr.out", "w", stdout);
	scanf("%d%d\n", &n, &k);
	fgets(S + 1, NMAX, stdin);
	int step = 0;
	for(; (1<<step) <= n; ++step); step--;
	int sol = 0;
	for(int i = step; i >= 0; --i)
		if(sol + (1<<i) <= n && valid(sol + (1<<i)) ) sol += (1<<i);
	printf("%d\n", sol);
	return 0;
}