Cod sursa(job #1693982)

Utilizator Andrei1998Andrei Constantinescu Andrei1998 Data 24 aprilie 2016 14:37:24
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.02 kb
#include <fstream>
#include <string>
#include <vector>
#include <cctype>

using namespace std;

const short NMAX = 17005;

short n, k;
string str;

struct State {
    short len, link;
    short tranz[26 + 26 + 10 + 1];

    short endpos_sz;
} states[2 * NMAX];

short sz, last;

void init() {
    states[0].link = -1;
}

void extend(char ch) {
    int current = ++ sz;
    states[current].len = states[last].len + 1;
    states[current].endpos_sz = 1;

    int p;
    for (p = last; p != -1 && !states[p].tranz[ch]; p = states[p].link)
        states[p].tranz[ch] = current;

    if (p != -1) {
        int q = states[p].tranz[ch];

        if (states[p].len + 1 == states[q].len)
            states[current].link = q;
        else {
            int clone = ++ sz;

            states[clone] = states[q];
            states[clone].len = states[p].len + 1;
            states[clone].endpos_sz = 0;

            for (; p != -1 && states[p].tranz[ch] == q; p = states[p].link)
                states[p].tranz[ch] = clone;

            states[current].link = states[q].link = clone;
        }
    }

    last = current;
}

vector <int> lengths[NMAX];

int main()
{
    ifstream cin("substr.in");
    ofstream cout("substr.out");

    cin >> n >> k;
    cin >> str;

    init();
    for (auto it: str)
        if (islower(it))
            extend(it - 'a' + 1);
        else if (isupper(it))
            extend(it - 'A' + 26 + 1);
        else
            extend(it - '0' + 26 + 26 + 1);

    //Getting endpos_szs
    for (int i = 1; i <= sz; ++ i)
        lengths[states[i].len].push_back(i);
    for (int i = n; i; -- i)
        for (auto it: lengths[i])
            states[states[it].link].endpos_sz += states[it].endpos_sz;

    //Getting answer
    int best = 0;
    for (int i = 1; i <= sz; ++ i)
        if (states[i].endpos_sz >= k && states[i].len > best)
            best = states[i].len;

    cout << best << '\n';

    cin.close();
    cout.close();
    return 0;
}