Cod sursa(job #2390900)

Utilizator preda.andreiPreda Andrei preda.andrei Data 28 martie 2019 14:24:16
Problema Substr Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.66 kb
#include <algorithm>
#include <fstream>
#include <string>
#include <vector>

using namespace std;

struct SortData
{
    pair<int, int> halves;
    int index;

    bool operator<(const SortData &other) const
    {
        return halves < other.halves;
    }

    bool operator!=(const SortData &other) const
    {
        return halves != other.halves;
    }
};

vector<int> Normalise(vector<SortData> &vec)
{
    sort(vec.begin(), vec.end());

    vector<int> normal(vec.size());
    normal[vec[0].index] = 0;

    for (size_t i = 1; i < vec.size(); i += 1) {
        normal[vec[i].index] = normal[vec[i - 1].index];
        if (vec[i] != vec[i - 1]) {
            normal[vec[i].index] += 1;
        }
    }
    return normal;
}

vector<int> Normalise(const string &str)
{
    vector<SortData> vec(str.size());
    for (size_t i = 0; i < str.size(); i += 1) {
        vec[i].halves = {str[i], -1};
        vec[i].index = i;
    }
    return Normalise(vec);
}

vector<vector<int>> GetOrder(const string &str)
{
    vector<vector<int>> order;
    order.push_back(Normalise(str));

    for (auto i = 1; (1 << (i - 1)) <= (int)str.size(); i += 1) {
        vector<SortData> vec(str.size());
        for (size_t j = 0; j < str.size(); j += 1) {
            vec[j].index = j;
            vec[j].halves.first = order[i - 1][j];

            if (j + (1 << (i - 1)) < str.size()) {
                vec[j].halves.second = order[i - 1][j + (1 << (i - 1))];
            } else {
                vec[j].halves.second = -1;
            }
        }
        order.push_back(Normalise(vec));
    }

    return order;
}

int FindLongestPrefix(const vector<vector<int>> &order, size_t x, size_t y)
{
    auto res = 0;
    for (int i = order.size() - 1; i >= 0; i -= 1) {
        if (x + (1 << i) > order[0].size() || y + (1 << i) > order[0].size()) {
            continue;
        }
        if (order[i][x] == order[i][y]) {
            res += (1 << i);
            x += (1 << i);
            y += (1 << i);
        }
    }
    return res;
}

int FindSubstringLen(const string &str, int times)
{
    auto res = 0;
    auto order = GetOrder(str);

    vector<int> indexes(str.size());
    for (size_t i = 0; i < str.size(); i += 1) {
        indexes[order.back()[i]] = i;
    }

    for (size_t i = 0; i + times <= str.size(); i += 1) {
        auto a = indexes[i];
        auto b = indexes[i + times - 1];
        res = max(res, FindLongestPrefix(order, a, b));
    }
    return res;
}

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

    int len, times;
    fin >> len >> times;
    fin.get();

    string str;
    fin >> str;

    auto res = FindSubstringLen(str, times);
    fout << res << "\n";

    return 0;
}