Cod sursa(job #3142628)

Utilizator daristyleBejan Darius-Ramon daristyle Data 22 iulie 2023 22:12:48
Problema Substr Scor 30
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.89 kb
#include <fstream>

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

const int N_MAX = (1 << 14);
const int HASHES = 2;
const int MODS[] = {666013, 9001};
const int MOD_MAX = 666013;
const int BASE = 31;
const int OFFSET = 'a' - 1;

int lgpow(int b, int e, int mod){
	int p = 1;
	while(e){
		if(e & 1)
			p = (long long) p * b % mod;
		b = (long long) b * b % mod;
		e >>= 1;
	}

	return p;
}

struct Hash{
		int value, mod, base, base_power;

		void init(int _mod, int _base, int len){
			value = 0;
			mod = _mod;
			base = _base;
			base_power = lgpow(base, len - 1, mod);
		}

		void add(char ch){
			value = ((long long) value * base % mod + ch - OFFSET);
			if(value >= mod)
				value -= mod;

		}

		void remove(char ch){
			value = value - ((long long) (ch - OFFSET) * base_power % mod);
			if(value < 0)
				value += mod;
		}

		int compute(char* s, int slen){
			int val = 0;
			for(int i = 0; i < slen; ++i){
				val = ((long long) val * base % mod + s[i] - OFFSET);
				if(val >= mod)
					val -= mod;
			}

			return val;
		}
};

char s[N_MAX + 1];
short f[MOD_MAX];

int max(short v[], int n){
	int max = v[0];
	for(int i = 1; i < n; ++i)
		if(max < v[i])
			max = v[i];

	return max;
}

bool Check(int len, int k, char s[], int slen){
	Hash h;
	int it = 0;
	bool ret = true;
	while(it < HASHES && ret){
		for(int i = 0; i < MODS[it]; ++i)
			f[i] = 0;

		h.init(MODS[it], BASE, len);
		h.value = h.compute(s, len - 1);

		for(int i = len - 1; i < slen; ++i){
			h.add(s[i]);
			if(h.value >= MODS[it])
				exit(7);
			++f[h.value];
			h.remove(s[i-len + 1]);
		}

		if(max(f, MODS[it]) < k)
			ret = false;


		++it;
	}

	return ret;
}

int main(){
	int slen, k;
	fin >> slen >> k >> s;

	int b = 0, e = slen - k + 1, mid;

	while(e - b > 1){
		mid = (b + e) / 2;
		if(Check(mid, k, s, slen))
			b = mid;
		else
			e = mid;
	}

	fout << b << '\n';

	fin.close();
	fout.close();
	return 0;
}