Cod sursa(job #1583499)

Utilizator StarGold2Emanuel Nrx StarGold2 Data 28 ianuarie 2016 23:56:48
Problema Substr Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.55 kb
#include <cstdio>
#include <algorithm>
#include <set>
#include <iterator>

const int P1 = 23;
const int P2 = 29;
const int M1 = 100007;
const int M2 = 100023;
const int DIM = 1 << 15;
using namespace std;

char S[DIM]; int N, K, l, r, m;
multiset <pair <int, int> > my_set;

int solve( int L ) {
    my_set.clear();
    int V1 = 0, V2 = 0, H1 = 1, H2 = 1;

    for( int i = 0; i < L; i ++ ) {
        V1 = (V1 * P1 + S[i]) % M1;
        V2 = (V2 * P2 + S[i]) % M2;

        if( i ) {
            H1 = (H1 * P1) % M1;
            H2 = (H2 * P2) % M2;
        }
    }

    my_set.insert( make_pair( V1, V2 ));

    for( int i = L; i < N; i ++ ) {
        V1 = ((V1 - (S[i - L] * H1) % M1 + M1) * P1 + S[i]) % M1;
        V2 = ((V2 - (S[i - L] * H2) % M2 + M2) * P2 + S[i]) % M2;

        my_set.insert( make_pair( V1, V2 ));

        multiset< pair<int, int> > :: iterator it1 = my_set.lower_bound( make_pair( V1, V2 ) );
        multiset< pair<int, int> > :: iterator it2 = my_set.upper_bound( make_pair( V1, V2 ) );

        if( distance( it1, it2 ) >= K )
            return 1;
    }

    return 0;
}

int main () {

    freopen( "substr.in" , "r", stdin  );
    freopen( "substr.out", "w", stdout );

    scanf( "%d %d %s", &N, &K, S );

    if( K == 1 ) {
        printf( "%d\n", N );
        return 0;
    }

    l = 1; r = N;
    while( l <= r ) {
        m = l + (r - l) / 2;

        if( solve( m ))
            l = m + 1;
        else
            r = m - 1;
    }

    printf( "%d\n", r );

    return 0;
}