Cod sursa(job #1749109)

Utilizator AlexNiuclaeNiculae Alexandru Vlad AlexNiuclae Data 27 august 2016 21:21:59
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.88 kb
///Centrul InfO(1) - Suffix Array
///Niculae Alexandru Vlad

#include <bits/stdc++.h>

using namespace std;

const int log_max = 14;
const int n_max = (1 << 14) + 10;

int p[log_max+1][n_max];
pair < pair < int , int > , int > v[n_max];

int n , k;
string s;

void read_data()
{
    ifstream fin("substr.in");
    fin >> n >> k >> s;
    s = ' ' + s;
}

void run_suffix_array()
{
    int i , j;

    for (i = 1; i <= n; ++i) p[0][i] = s[i] - 'a'; ///initializez p[0]
    for (i = 1; (1 << i) <= n; ++i)
    {
        for (j = 1; j <= n; ++j)
        {
            v[j].first = {p[i-1][j] , (j+(1<<(i-1))<=n) ? p[i-1][j+(1<<(i-1))] : -1}; ///creez perechile
            v[j].second = j; ///sufixul [j..n]
        }

        sort(v + 1 , v + n + 1);

        for (j = 1; j <= n; ++j)
            p[i][v[j].second] = p[i][v[j-1].second] + (v[j].first != v[j-1].first);
    }
}

int lcp(int a , int b) ///longest common prefix
{
    if (a == b) return n - a + 1;

    int ret = 0;

    for (int i = log_max; i >= 0; --i)
        if ((1 << i) <= n && p[i][a] == p[i][b])
            a += (1 << i), b += (1 << i), ret += (1 << i);

    return ret;
}

///trebuie sa gasesc un prefix care apare de cel putin k ori
///deci voi lua maximul lcp-urilor pentru orice secventa de lungime k din vectorul sortat (este optim)
///sa zicem ca vom lua k sufixuri : x1 < x2 < ... < xk
///lcp-ul lor este lcp(x1,xk), care lcp(x1,xk) = min(lcp(x1,x1+1),lcp(x1+1,x1+2),...,lcp(xk-1,xk))
///deci optim va fi orice secventa de lungime k
int get_ans()
{
    int ret = 0;
    for (int i = 1; i <= n - k + 1; ++i)
        ret = max(ret , lcp(v[i].second , v[i+k-1].second));

    return ret;
}

void print_answer()
{
    ofstream fout("substr.out");
    fout << get_ans() << '\n';
}

int main()
{
    read_data();
    run_suffix_array();
    print_answer();

    return 0;
}