Pagini recente » Cod sursa (job #1229818) | Cod sursa (job #2449524) | Cod sursa (job #2036987) | Cod sursa (job #2804044) | Cod sursa (job #3142648)
#include <fstream>
using namespace std;
ifstream fin("substr.in");
ofstream fout("substr.out");
const int N_MAX = (1 << 14);
const int HASHES = 3;
const int MODS[] = {9001,666013, 1000193};
const int MOD_MAX = 1000193;
const int BASE = 512;
const int OFFSET = 0;
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]);
++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;
fin.get();
fin.getline(s, slen + 1);
int b = 0, e = slen - k + 1 + 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;
}