Cod sursa(job #1581572)

Utilizator laurageorgescuLaura Georgescu laurageorgescu Data 26 ianuarie 2016 21:57:03
Problema Substr Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.93 kb
#include<fstream>
#include<string>
#include<cstring>
#include<vector>

using namespace std;

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

const int mod1 = 666013;
const int mod2 = 96235;
const int base = 62;
int n, k;

string s;

struct str{
    int val, m2;

    str() {}
    str( int _val, int _m2 ) {
        val = _val, m2 = _m2;
    }
};
vector< str > h[ mod1 ];

bool ok_and_update( int k1, int k2 ) {
    for( vector< str >::iterator it = h[ k1 ].begin(); it != h[ k1 ].end(); ++ it ) {
        if ( (it -> m2) == k2 ) {
            ++ (it -> val);
            return (it -> val) >= k;
        }
    }
    h[ k1 ].push_back( str( 1, k2 ) );
    return ( 1 >= k );
}
inline int val( char x ) {
    if ( x >= '0' && x <= '9' ) {
        return x - '0';
    }
    if ( x >= 'a' && x <= 'z' ) {
        return 10 + x - 'a';
    }
    return 10 + 26 + x - 'A';
}
bool check( int lg ) {
    for( int i = 0; i < mod1; ++ i ) {
        h[ i ].clear();
    }
    int p1 = 1, p2 = 1, key1 = 0, key2 = 0;
    for( int i = 0; i < lg - 1; ++ i, p1 = (p1 * base) % mod1, p2 = (p2 * base) % mod2 ) {
        key1 = ( key1 * base + val( s[ i ] ) ) % mod1;
        key2 = ( key2 * base + val( s[ i ] ) ) % mod2;
    }
    for( int i = lg - 1; i < n; ++ i ) {
        key1 = ( key1 * base + val( s[ i ] ) ) % mod1;
        key2 = ( key2 * base + val( s[ i ] ) ) % mod2;

        if ( ok_and_update( key1, key2 ) ) {
            return 1;
        }
        key1 = ( ( key1 - val( s[ i - lg + 1 ] ) * p1 ) % mod1 + mod1 ) % mod1;
        key2 = ( ( key2 - val( s[ i - lg + 1 ] ) * p2 ) % mod2 + mod2 ) % mod2;
    }
    return 0;
}
int main() {
    fin >> n >> k >> s;

    int n2, ans;
    for( n2 = 1; (n2 << 1) <= n; n2 <<= 1 ) {
    }
    ans = 0;
    for( int step = n2; step > 0; step >>= 1 ) {
        if ( ans + step <= n && check( ans + step ) ) {
            ans += step;
        }
    }
    fout << ans << "\n";
    fin.close();
    fout.close();
    return 0;
}