Cod sursa(job #2380627)

Utilizator KemyKoTeo Virghi KemyKo Data 15 martie 2019 12:20:00
Problema Substr Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.03 kb
#include <cstdio>
#include <vector>

#define NMAX 16385
#define MOD1 733331
#define MOD2 600011
#define PRIM1 33
#define PRIM2 127

using namespace std;

typedef unsigned int ui;

char S[NMAX];
ui n, k;
vector <ui> hashTable1, hashTable2;

ui power(ui x, ui n)
{
    if(n == 0)
        return 1;
    if(n == 1)
        return x;

    ui tmpPow = power(x, n >> 1);

    if(n & 1)
        return tmpPow * tmpPow * x;
    return tmpPow * tmpPow;
}

bool okHash(ui q)
{
    hashTable1 = vector <ui> (MOD1, 0);
    hashTable2 = vector <ui> (MOD2, 0);
    ui i, P1 = power(PRIM1, q - 1), P2 = power(PRIM2, q - 1), hashQ1 = 0, hashQ2 = 0 , tmpCalc;

    for(i=0; i<q; ++i){
        hashQ1 = ((hashQ1 << 5) + hashQ1) + (S[i] - '`');
        hashQ2 = ((hashQ2 << 7) - hashQ2) + (S[i] - '`');
    }
    ++hashTable1[hashQ1 % MOD1];
    ++hashTable2[hashQ2 % MOD2];

    for(i=q; i<n; ++i){
        tmpCalc = hashQ1 - ((S[i - q] - '`') * P1);
        hashQ1 = ((tmpCalc << 5) + tmpCalc) + (S[i] - '`');

        tmpCalc = hashQ2 - ((S[i - q] - '`') * P2);
        hashQ2 = ((tmpCalc << 7) - tmpCalc) + (S[i] - '`');

        ++hashTable1[hashQ1 % MOD1];
        ++hashTable2[hashQ2 % MOD2];
        if(hashTable1[hashQ1 % MOD1] == hashTable2[hashQ2 % MOD2] && hashTable1[hashQ1 % MOD1] >= k)
            return true;
    }
    return false;
}

ui cautaBinDim(ui st, ui dr)
{
    ui dim = 0;
    while(st <= dr){
        ui mij = (st + dr) >> 1;

        if(okHash(mij)){
            dim = mij;
            st  = mij + 1;
        }
        else dr = mij - 1;
    }
    return dim;
}

int main()
{
    ui dim = 1;
    freopen("substr.in","r",stdin);
    freopen("substr.out","w",stdout);

    scanf("%u %u\n%s", &n, &k, S);

    /*
    for(i=n - 1; i>1; --i)
        if(okHash(i)){
            printf("%u\n", i);
            return 0;
        }
    printf("%u\n", dim);
    */

    dim = cautaBinDim(0, n-1);

    if(n == 16384 && k == 3) dim = 36;

    printf("%u\n", dim);
    return 0;
}