Cod sursa(job #1417637)

Utilizator ZenusTudor Costin Razvan Zenus Data 10 aprilie 2015 18:27:30
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.13 kb
#include <fstream>
#include <string>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

#define NMAX 16390

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

string str;
pair < int , int > codQ;
vector < pair < pair < int , int > , int > > h[NMAX];
int le,ri,len,sol,N,K,p[2],cod[2];
const int base[] = {137,141,1371};
const int MOD[] = {666013,512731,NMAX};

int Find(pair < int , int > codQ)
{
    int idx = (1ll * codQ.first * base[2] + codQ.second) % MOD[2];

    for (int i=0;i<h[idx].size();++i)
    if (h[idx][i].first == codQ) return h[idx][i].second;

    return 0;
}

void Add(pair < int , int > codQ)
{
    int idx = (1ll * codQ.first * base[2] + codQ.second) % MOD[2];

    for (int i=0;i<h[idx].size();++i)
    if (h[idx][i].first == codQ)
    {
        h[idx][i].second += 1;
        return ;
    }
}

void Insert(pair < int , int > codQ)
{
    int idx = (1ll * codQ.first * base[2] + codQ.second) % MOD[2];

    if (Find(codQ)) Add(codQ);
    else h[idx].push_back({codQ,1});
}

bool check(int len)
{
    for (int i=0;i<MOD[2];++i)
    h[i].clear();

    cod[0] = cod[1] = 0;
    p[0] = p[1] = 1;

    // p[k] = base[k] ^ len

    for (int i=0;i<len;++i)
    for (int k=0;k<=1;++k)
    {
        cod[k] = ( 1ll * cod[k] * base[k] + str[i]) % MOD[k];
        p[k] = (1ll * p[k] * base[k]) % MOD[k];
    }

    codQ = {cod[0] , cod[1]};
    Insert(codQ);
    if (Find(codQ) >= K) return true;

    for (int i=len;i<N;++i)
    {
        for (int k=0;k<=1;++k)
        {
            cod[k] = (1ll * cod[k] * base[k] + str[i]) % MOD[k];
            cod[k] = (cod[k] - ( (1ll * p[k] * str[i - len]) % MOD[k] ) + MOD[k]) % MOD[k];
        }

        codQ = {cod[0] , cod[1]};
        Insert(codQ);
        if (Find(codQ) >= K) return true;
    }

    return false;
}

int main()
{

f >> N >> K >> str;

le = 1 ; ri = N ;

while (le <= ri)
{
    len = (le + ri) >> 1;

    if (check(len))
    {
        le = len + 1;
        sol = len;
    } else ri = len - 1;
}

g << sol << '\n';

return 0;
}