Cod sursa(job #1418571)

Utilizator AlexNiuclaeNiculae Alexandru Vlad AlexNiuclae Data 13 aprilie 2015 14:42:17
Problema Substr Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.03 kb
#include <cstdio>
#include <algorithm>
#include <vector>

#define Nmax 16390
#define MOD 666013

#define code first
#define nr second

using namespace std;

const int Mod[3] = {699967 , 698669 , 693881};
const int p[3] = {1371 , 131 , 137};

int n , k;
int hashing[3] , P[3];

vector < pair < int , int > > H[MOD];

char S[Nmax];

int number(int xhashing , bool mod)
{
    int ind = xhashing % MOD;

    for (int i = 0; i < H[ind].size(); ++i)
        if (H[ind][i].code == xhashing)  if (mod) return H[ind][i].nr;
                                         else {H[ind][i].nr++; return 1;}
    return 0;
}

void baga(int xhashing)
{
    if (number(xhashing , 0) > 0) return;

    H[xhashing % MOD].push_back({xhashing , 1});
}

bool check(int lenght)
{
    int i , ind;

    for (i = 0; i < MOD; ++i)
        H[i].clear();

    hashing[1] = hashing[2] = 0;

    for (i = 1; i <= lenght; ++i)
     for (ind = 1; ind <= 2; ++ind)
      hashing[ind] = (1LL * hashing[ind] * p[ind] + S[i]) % Mod[ind],
      (i > 1) ? P[ind] = (1LL * P[ind] * p[ind]) % Mod[ind] : P[ind] = 1;

    hashing[0] = (1LL * hashing[1] * p[0] + hashing[2]) % Mod[0];

    baga(hashing[0]);

    if (number(hashing[0] , 1) >= k) return true;

    for (i = lenght + 1; i <= n; ++i)
    {
        for (ind = 1; ind <= 2; ++ind)
            hashing[ind] = (1LL * (hashing[ind] - (1LL * S[i-lenght] * P[ind]) % Mod[ind] + Mod[ind]) * p[ind] + S[i]) % Mod[ind];

        hashing[0] = (1LL * hashing[1] * p[0] + hashing[2]) % Mod[0];

        baga(hashing[0]);

        if (number(hashing[0] , 1) >= k)
            return true;
    }

    return false;
}

int solve()
{
    int i , step;

    for (step = 1; step < n; step <<= 1);

    for (i = 0; step; step >>= 1)
     if (check(i + step))
        i += step;

    return i;
}

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

    scanf("%d %d\n", &n, &k);

    gets(S+1);

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

    return 0;
}