Cod sursa(job #2265794)

Utilizator preda.andreiPreda Andrei preda.andrei Data 21 octombrie 2018 18:13:37
Problema Prefix Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.76 kb
#include <fstream>
#include <string>
#include <vector>

using namespace std;

size_t SamePrefixLen(const string &str, size_t left, size_t right)
{
    size_t len = 0;
    while (right + len < str.size() && str[left + len] == str[right + len]) {
        len += 1;
    }
    return len;
}

vector<size_t> GetZVec(const string &str)
{
    vector<size_t> zvec(str.size(), 0);
    size_t left = 0, right = 0;

    for (size_t i = 1; i < str.size(); i += 1) {
        if (i > right) {
            zvec[i] = SamePrefixLen(str, 0, i);
            left = i;
            right = i + zvec[i] - 1;
            continue;
        }

        auto other = i - left;
        auto len_to_right = right - i + 1;

        if (zvec[other] < len_to_right) {
            zvec[i] = zvec[i];
        } else {
            auto extra = SamePrefixLen(str, len_to_right, right + 1);
            zvec[i] = len_to_right + extra;
            left = i;
            right = i + zvec[i] - 1;
        }
    }
    return zvec;
}

size_t MaxPeriodicPrefix(const vector<size_t> &zvec, size_t period)
{
    if (period <= 0 || zvec[period] < period) {
        return 0;
    }

    auto len = period;
    while (len < zvec.size() && zvec[len] >= period) {
        len += period;
    }
    return len;
}

int FindPeriod(const string &str)
{
    auto zvec = GetZVec(str);
    auto period = 0;

    for (size_t i = 1; i <= str.size() / 2; i += 1) {
        period = max<size_t>(period, MaxPeriodicPrefix(zvec, i));
    }
    return period;
}

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

    int tests;
    fin >> tests;
    fin.get();

    for (auto i = 0; i < tests; i += 1) {
        string str;
        getline(fin, str);

        auto res = FindPeriod(str);
        fout << res << "\n";
    }

    return 0;
}