Cod sursa(job #1146808)

Utilizator chiriacandrei25Chiriac Andrei chiriacandrei25 Data 19 martie 2014 12:07:51
Problema Substr Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.28 kb
#include <cstdio>
#include <vector>
#define Nmax 17000
#define P1 (1<<17)
#define P2 (1<<15)
#define X 6453432
#define Y 1234567

using namespace std;

int N,K;
char a[Nmax];
vector <int> H1[P1+10],H2[P2+10];

inline void AdaugaHash1(int x)
{
    int i=(x&(P1-1));
    H1[i].push_back(x);
}

inline void AdaugaHash2(int x)
{
    int i=(x&(P2-1));
    H2[i].push_back(x);
}

inline int CautaHash1(int x)
{
    int i=(x&(P1-1)),cnt=0;
    vector<int>::iterator it;
    for(it=H1[i].begin();it!=H1[i].end();++it)
        if(*it==x)
            ++cnt;
    return cnt;
}

inline int CautaHash2(int x)
{
    int i=(x&(P2-1)),cnt=0;
    vector<int>::iterator it;
    for(it=H2[i].begin();it!=H2[i].end();++it)
        if(*it==x)
            ++cnt;
    return cnt;
}

inline bool Ok(int L)
{
    int v1=0,v2=0,aux1=1,aux2=1,i;
    for(i=1;i<L;++i)
    {
        aux1=((1LL*aux1*X)&(P1-1));
        aux2=((1LL*aux2*Y)&(P2-1));
    }
    for(i=1;i<=L;++i)
    {
        v1=((1LL*v1*X+a[i]-'0')&(P1-1));
        v2=((1LL*v2*Y+a[i]-'0')&(P2-1));
    }
    AdaugaHash1(v1); AdaugaHash2(v2);
    for(i=L+1;i<=N;++i)
    {
        v1=(((1LL*((v1-(1LL*(a[i-L]-'0')*aux1)&(P1-1))+P1)&(P1-1))*X+a[i]-'0')&(P1-1));
        v2=(((1LL*((v2-(1LL*(a[i-L]-'0')*aux2)&(P2-1))+P2)&(P2-1))*Y+a[i]-'0')&(P2-1));
        AdaugaHash1(v1);
        AdaugaHash2(v2);
    }
    v1=v2=0;
    for(i=1;i<=L;++i)
    {
        v1=((1LL*v1*X+a[i]-'0')&(P1-1));
        v2=((1LL*v2*Y+a[i]-'0')&(P2-1));
    }
    if(CautaHash1(v1)>=K && CautaHash2(v2)>=K)
        return true;
    for(i=L+1;i<=N;++i)
    {
        v1=((((1LL*((v1-(1LL*(a[i-L]-'0')*aux1)&(P1-1))+P1))&(P1-1))*X+a[i]-'0')&(P1-1));
        v2=((((1LL*((v2-(1LL*(a[i-L]-'0')*aux2)&(P2-1))+P2))&(P2-1))*Y+a[i]-'0')&(P2-1));
        if(CautaHash1(v1)>=K && CautaHash2(v2)>=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=2*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;
}