Cod sursa(job #1768105)

Utilizator ionutpop118Pop Ioan Cristian ionutpop118 Data 30 septembrie 2016 10:48:59
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.98 kb
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>

using namespace std;
const int mod1 = 100003;
const int mod2 = 100153;

int n, k; char s[16400];
vector < pair <int, int> > g[mod1];
pair <int, int> sigmamod[16400];

int alpha(char x)
{
    if(x >= '0' && x <= '9')
        return 1 + x - '0';
    else if(x >= 'a' && x <= 'z')
        return 11 + x - 'a';
    else return 37 + x - 'A';
}

void update (int x1, int x2, int &Max)
{
    for (int i = 0; i < g[x1].size(); ++i)
        if (g[x1][i].first == x2)
        {
            Max = max(Max, ++g[x1][i].second);
            return ;
        }
    g[x1].push_back( make_pair(x2, 1));
    Max = max(Max, 1);
}

int RabinKerp(int l)
{
    int val1 = 0, val2 = 0, nr = 0, Mmax = 0;
    for (int i = 1; i <= n; ++i)
    {
        val1 = (val1 * 63 + alpha(s[i])) % mod1;
        val2 = (val2 * 63 + alpha(s[i])) % mod2;
        ++nr;

        if (nr > l)
        {
           val1 = (100 * mod1 + val1 - alpha(s[i - l]) * sigmamod[l].first ) % mod1;
           val2 = (100 * mod2 + val2 - alpha(s[i - l]) * sigmamod[l].second ) % mod2;
           --nr;
        }
        if (nr == l)
            update(val1, val2, Mmax);
    }

    return Mmax;
}

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

    int st, dr, med, last;
    scanf("%d %d\n", &n, &k);
    gets(s + 1);

    sigmamod[0] = make_pair(1 ,1);
    for (int i = 1; i <= n; ++i)
    {
        sigmamod[i].first = (sigmamod[i - 1].first * 63) % mod1;
        sigmamod[i].second = (sigmamod[i - 1].second * 63) % mod2;
    }

    /// cautare binara ///
    st = 1; dr = n; last = 0;
    while (st <= dr)
    {
        med = ((st + dr) >> 1);
        if (RabinKerp(med) >= k)
        {
            last = med;
            st = med + 1;
        }
        else
            dr = med - 1;
        memset(g, 0, sizeof(g));
    }
    printf("%d", last);
    return 0;
}