Cod sursa(job #2322274)

Utilizator alexge50alexX AleX alexge50 Data 17 ianuarie 2019 17:16:47
Problema Prefix Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.94 kb
/*
 *  Software sellers want to divide the users and conquer them, making each
 *  user agree not to share with others.
 *     - Richard Stallman
 */

#include <iostream>
#include <fstream>
#include <vector>
#include <numeric>

class Range;
class NumericIterator
{
private:
    explicit NumericIterator(int start): m_i{start} {};
public:
    NumericIterator(): m_i{0} {}
    NumericIterator(const NumericIterator &) = default;
    NumericIterator(NumericIterator &&) = default;

    long int operator *() const { return m_i; }
    const NumericIterator &operator ++() { m_i++; return *this; }
    NumericIterator operator ++(int) { NumericIterator temp = *this; m_i++; return temp; }

    bool operator ==(const NumericIterator &other) const { return m_i == other.m_i; }
    bool operator !=(const NumericIterator &other) const { return m_i != other.m_i; }

private:
    int m_i;
    friend Range;
};

class Range
{
public:
    Range(int start, int end): m_start{start}, m_end{end}{}

    NumericIterator begin() { return NumericIterator{m_start}; }
    NumericIterator end() { return NumericIterator{m_end}; }
private:
    int m_start, m_end;
};

long long longestPeriodicPrefix(std::string str)
{
    str = ' ' + str;

    std::vector<int> pi;
    pi.insert(pi.begin(), str.size(), {});

    int lc = 0;
    for(int i = 2; i < str.size(); i++)
    {
        while(lc > 0 && str[i] != str[lc + 1])
            lc = pi[lc];
        if(str[i] == str[lc + 1])
            lc++;
        pi[i] = lc;
    }

    auto r = Range{1, static_cast<int>(str.size())};
    return std::accumulate(r.begin(), r.end(), 0, [&pi](int max, int i){
        if(pi[i] > 0 && i % (i - pi[i]) == 0)
            return i;
        else return max;
    });
}

int main()
{
    std::ifstream fin("prefix.in");
    std::ofstream fout("prefix.out");
    int t;
    std::string s;

    for(fin >> t; t > 0; t--)
    {
        fin >> s;
        fout << longestPeriodicPrefix(s) << std::endl;
    }

    return 0;
}