Cod sursa(job #1010314)

Utilizator Impaler_009Mihai Nitu Impaler_009 Data 14 octombrie 2013 18:32:27
Problema Substr Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.83 kb
#include <fstream>
#include <vector>
#include <utility>

#define maxn 17000
#define mod 666013
#define base 80
#define ll long long

using namespace std;

ifstream fin("substr.in");
ofstream fout("substr.out");

int n,k,lo,hi,mid,q[maxn];
string s;

vector <pair<short,short> > h[666013];

ll lgpow (ll a, ll b)
{
    if (b==0) return 1;
    ll x = lgpow (a,b/2);
    if (b%2) return x*x%mod*a;
    return x*x%mod;
}

bool eq (int i, int j)
{
    for (int k=0,h=0; k<mid && h<mid; ++k,++h)
    {
        if (s[i+k] != s[j+h])
            return 0;
    }
    return 1;
}

int hash_add (int m, int start)
{
    int N = h[m].size();

    for (int i=0; i<N; ++i)
    {
        if (eq(start,h[m][i].first))
        {
            ++h[m][i].second;
            return h[m][i].second;
        }
    }

    h[m].push_back (make_pair(start,1));
    return 1;
}

bool check (int l)
{
    int maxv = 0, t=0;
    long long hashval = 0;

    int i;
    for (i=0; i<l; ++i)
    {
        hashval = (hashval * base * 1LL % mod + (s[i]-'0'))%mod;
    }

    int val = hash_add (hashval,0);
    maxv = max (maxv,val);

    q[++t] = hashval;

    for (; i<n; ++i)
    {
        ll elim = (s[i-l]-'0') * lgpow (base,l-1);

        hashval = (hashval - elim)%mod;
        if (hashval < 0) hashval += mod;

        hashval = (hashval * base * 1LL % mod + (s[i]-'0'))%mod;

        int val = hash_add (hashval,i-l+1);
        maxv = max (maxv,val);

        q[++t] = hashval;
    }

    for (int i=1; i<=t; ++i)
    {
        h[q[i]].clear();
    }

    if (maxv >= k) return 1;
    return 0;
}

int main()
{
    fin>>n>>k>>s;

    hi = n-k+2;
    lo = 0;

    while (hi - lo > 1)
    {
        mid = (lo+hi)/2;
        if (check(mid)) lo = mid;
        else hi = mid;
    }

    fout<<lo;
}