Cod sursa(job #1053932)

Utilizator maritimCristian Lambru maritim Data 13 decembrie 2013 01:04:32
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.26 kb
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;

ifstream f("substr.in");
ofstream g("substr.out");

struct xy
{
    int val1, val2, nr;
} ;

typedef vector<xy>::iterator it;

#define M 666013
#define MaxN 17000
#define MOD1 23131
#define MOD2 24121
#define mid ((li+ls)>>1)

int N,K;
int Put1[MaxN],Put2[MaxN];
pair<int,int> Aux[MaxN];
vector<xy> Hash[M];
char S[MaxN];

void citire(void)
{
    f >> N >> K >> (S+1);
}

inline xy make_xy(int val1,int val2,int nr)
{
    xy a = {val1,val2,nr};

    return a;
}

inline int addHash(int val1,int val2)
{
    int x = (val1+val2)%M;

    for(it i=Hash[x].begin();i<Hash[x].end();++i)
        if(i->val1 == val1 && i->val2 == val2)
        {
            ++ i->nr;

            return i->nr;
        }

    Hash[x].push_back(make_xy(val1,val2,1));

    return 1;
}

inline void eraseHash(int nr)
{
    for(int i=1;i<=nr;i++)
        Hash[(Aux[i].first+Aux[i].second)%M].clear();
}

void preprocesare(void)
{
    Put1[1] = Put2[1] = 1;

    for(int i=2;i<=N;i++)
        Put1[i] = (Put1[i-1]*256)%MOD1,
        Put2[i] = (Put2[i-1]*256)%MOD2;
}

inline int aparitii(int length)
{
    int Val1 = 0, Val2 = 0,nr = 0,aux = 0,k = 0;

    for(int i=1;i<=length;i++)
        Val1 = (Val1*256+S[i])%MOD1,
        Val2 = (Val2*256+S[i])%MOD2;

    aux = addHash(Val1,Val2);
    k = max(k,aux);
    if(aux == 1) Aux[++nr] = make_pair(Val1,Val2);
    //cout << Val1 << " " << Val2 << "\n";

    for(int i=length+1;i<=N;i++)
    {
        Val1 = (Val1+MOD1-(S[i-length]*Put1[length])%MOD1)%MOD1;
        Val1 = (Val1*256+S[i])%MOD1;
        Val2 = (Val2+MOD2-(S[i-length]*Put2[length])%MOD2)%MOD2;
        Val2 = (Val2*256+S[i])%MOD2;

        //cout << i << " " << Val1 << " " << Val2 << "\n";

        aux = addHash(Val1,Val2);
        k = max(k,aux);
        if(aux == 1) Aux[++nr] = make_pair(Val1,Val2);
        //cout << "............... " << aux << "\n";
    }

    eraseHash(nr);

    return k;
}

inline int cautBin(int li,int ls)
{
    if(li > ls)
        return ls;

    if(aparitii(mid) >= K)
        return cautBin(mid+1,ls);
    else
        return cautBin(li,mid-1);
}

int main()
{
    citire();
    preprocesare();
    //for(int i=1;i<=N;i++)
    //    cout << "ysadhasdas : " << i << "  " << aparitii(i) << "\n";
    g << cautBin(1,N);
}