Pagini recente » Cod sursa (job #678911) | Cod sursa (job #2904907) | Cod sursa (job #631994) | Cod sursa (job #2688565) | Cod sursa (job #3142713)
#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[] = {666013, (int) 1e9 + 7, (int) 1e9 + 21};
const int BASE = 256;
const int OFFSET = '0';
const int NIL = -1;
template<typename Key, typename Value>
class Dictionary{
private:
static const int MOD = 65353;
struct Node{
Key key;
Value value;
};
Node node[N_MAX];
int nxt[N_MAX];
int head[MOD];
int n;
int hash(Key key){
return key % MOD;
}
int find(Key x){
int list = hash(x);
int l = head[list];
while(l != NIL && node[l].key != x)
l = nxt[l];
return l;
}
public:
Dictionary(){
for(int i = 0; i < N_MAX; ++i)
nxt[i] = NIL;
for(int i = 0; i < MOD; ++i)
head[i] = NIL;
n = 0;
}
void add(Node x){
int list = hash(x.key);
node[n] = x;
nxt[n] = head[list];
head[list] = n;
++n;
}
void remove(Key x){
int list = hash(x);
int l = head[list], prev = NIL;
while(l != NIL && node[l].key != x){
prev = l;
l = nxt[l];
}
if(node[l].key == x){
if(prev == NIL)
head[list] = nxt[l];
else
nxt[prev] = nxt[l];
}
}
const Value translate(Key x){
int pos = find(x);
Value ret{};
if(pos != NIL)
ret = node[pos].value;
return ret;
}
Value& operator[](Key x){
int pos = find(x);
if(pos == NIL){
Value aux{};
add({x, aux});
pos = n - 1;
}
return node[pos].value;
}
void clear(){
for(int i = 0; i < n; ++i)
nxt[i] = NIL;
for(int i = 0; i < MOD; ++i)
head[i] = NIL;
n = 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 = ((unsigned long long) value * base % mod + ch - OFFSET);
if(value >= mod)
value -= mod;
}
void remove(char ch){
value = value - ((unsigned 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 = ((unsigned long long) val * base % mod + s[i] - OFFSET);
if(val >= mod)
val -= mod;
}
return val;
}
};
char s[N_MAX + 1];
Dictionary<int, short> f;
bool Check(int len, int k, char s[], int slen){
Hash h;
int it = 0;
bool ret = true;
while(it < HASHES && ret){
h.init(MODS[it], BASE, len);
h.value = h.compute(s, len - 1);
int max = 0;
for(int i = len - 1; i < slen; ++i){
h.add(s[i]);
++f[h.value];
if(f[h.value] > max)
max = f[h.value];
h.remove(s[i - len + 1]);
}
if(max < k)
ret = false;
f.clear();
++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;
}