Cod sursa(job #1418612)

Utilizator AlexNiuclaeNiculae Alexandru Vlad AlexNiuclae Data 13 aprilie 2015 15:19:54
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.11 kb
#include <cstdio>
#include <algorithm>
#include <vector>

#define Nmax 16390

#define code first
#define nr second

using namespace std;

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

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

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

char S[Nmax];

int number(pair < int , int > xhashing , bool mod)
{
    int ind = (1LL * xhashing.first * p[0] + xhashing.second) % Mod[0];

    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(pair < int , int > xhashing)
{
    if (number(xhashing , 0) > 0) return;

    int ind = (1LL * xhashing.first * p[0] + xhashing.second) % Mod[0];

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

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

    for (i = 0; i < Mod[0]; ++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;

    baga({hashing[1] , hashing[2]});

    if (number({hashing[1] , hashing[2]} , 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];

        baga({hashing[1] , hashing[2]});

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

    return false;
}

int solve()
{
    int i , step;

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

    for (i = 0; step; step >>= 1)
     if (i + step + k - 1 <= n && 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;
}