Cod sursa(job #1148756)

Utilizator chiriacandrei25Chiriac Andrei chiriacandrei25 Data 21 martie 2014 08:14:00
Problema Substr Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.06 kb
#include <cstdio>
#include <vector>
#define Nmax 17000
#define P 100021
#define X 61

using namespace std;

int N,K;
char a[Nmax];

struct str
{
    int codh, last;
    str() {codh = last = 0;}
    str(const int codh, const int last)
    {
        this -> codh = codh;
        this -> last = last;
    }
    bool operator <(const str & other ) const
    {
        return codh < other.codh;
    }
    bool operator == (const str & other ) const
    {
        return this -> codh == other.codh && this -> last == other.last;
    }
    bool operator ()(const str & other ) const
    {
        return codh < other.codh;
    }
};

vector <str> H[P+10];

inline void AdaugaHash(str x)
{
    int i=x.codh%P;
    H[i].push_back(x);
}

inline int CautaHash(str x)
{
    int i=x.codh%P,cnt=0;
    vector<str>::iterator it;
    for(it=H[i].begin();it!=H[i].end();++it)
        if(it->codh==x.codh && it->last==x.last)
            ++cnt;
    return cnt;
}

inline bool Ok(int L)
{
    int v=0,aux=1,i;
    str w;
    for(i=0;i<P;++i)
        H[i].clear();
    for(i=1;i<L;++i)
        aux=(1LL*aux*X)%P;
    for(i=1;i<=L;++i)
        v=(1LL*v*X+a[i]-'0')%P;
    AdaugaHash(str(v,a[L]-'0'));
    for(i=L+1;i<=N;++i)
    {
        v=(1LL*((v-(1LL*(a[i-L]-'0')*aux)%P+P)%P)*X+a[i]-'0')%P;
        AdaugaHash(str(v,a[i]-'0'));
    }
    v=0;
    for(i=1;i<=L;++i)
        v=(1LL*v*X+a[i]-'0')%P;
    if(CautaHash(str(v,a[i]-'0'))>=K)
        return true;
    for(i=L+1;i<=N;++i)
    {
        v=((1LL*((v-(1LL*(a[i-L]-'0')*aux)%P+P))%P)*X+a[i]-'0')%P;
        if(CautaHash(str(v,a[i]-'0'))>=K)
            return true;
    }
    return false;
}

int main()
{
    int st,dr,mij,sol;
    freopen ("substr.in","r",stdin);
    freopen ("substr.out","w",stdout);
    scanf("%d%d%s", &N,&K,(a+1));
    st=1; dr=N;
    while(st<=dr)
    {
        mij=(st+dr)/2;
        if(Ok(mij))
        {
            sol=mij;
            st=mij+1;
        }
        else
            dr=mij-1;
    }
    printf("%d\n", sol);
    return 0;
}