Cod sursa(job #624088)

Utilizator vlad2901Vlad Berindei vlad2901 Data 21 octombrie 2011 18:00:59
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.01 kb
#include <cstdio>
#define NMAX 16384
#define MOD 666013
#define BASE 76


struct list
{
    int key, pos;
    list *next;
} *H[MOD];

int n, k;
char s[NMAX];

int hash_insert(int key, int pos)
{
    list *current;
    int nr = 0;

    current = new list;
    current->key = key;
    current->pos = pos;
    current->next = H[key];
    H[key] = current;

    for(current=H[key];current;current=current->next)
    {
        nr++;
    }
    return nr;
}

int matches(int pos1, int pos2, int l)

{
    int i;
    for(i=0;i<l;++i)
    {
        if(s[pos1+i] != s[pos2+i])
        {
            return 0;
        }
    }
    return 1;
}

int check(int key, int pos, int l)
{
    list *c;
    int nr = 0;

    for(c=H[key];c;c=c->next)
    {
        if(matches(c->pos, pos, l))
        {
            ++nr;
        }
    }
    return nr;
}

int substr(int l)
{
    int i, key = 0, factor = 1;

    if(l==n)
    {
        return 1;
    }

    for(i=0;i<l-1;++i)
    {
        key = (key * BASE + s[i] - '0') % MOD;
        factor = (factor * BASE) % MOD;
    }

    key = (key * BASE + s[i] - '0') % MOD;

    hash_insert(key, 0);

    for(i=l;i<n;++i)
    {
        key = (BASE * (key - (factor * (s[i-l] - '0')) % MOD) + s[i] - '0') % MOD;
        if(key < 0)
        {
            key += MOD;
        }
        if(hash_insert(key, i-l+1) >= k)
        {
            if(check(key, i-l+1, l) >=k)
            {
                return 1;
            }
        }
    }
    return 0;
}

int main()
{
    int st, dr, m, sol;

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

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

    st = 1;
    dr = n;
    sol = 1;

    while(st <= dr)
    {
        m = (st + dr) / 2;

        if(substr(m))
        {
            st = m + 1;
            sol = m;
        }
        else
        {
            dr = m-1;
        }
    }

    printf("%d", sol);

    return 0;
}