Cod sursa(job #2316285)

Utilizator alexge50alexX AleX alexge50 Data 11 ianuarie 2019 15:34:25
Problema Plantatie Scor 50
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.59 kb
/*
 * The idea of copyright didn't exist in ancient times when authors frequently
 * copied other authors at length in works of non-fiction. This practice was
 * useful, and is only way many authors' works have survived even in part.
 *      - Richard Stallman
 */

#include <iostream>
#include <array>
#include <fstream>
#include <numeric>

const int MAX_N = 500;
const int LOG_MAX_N = 9;

using rmq = std::array<std::array<int, LOG_MAX_N>, MAX_N>;

std::array<int, MAX_N + 1> log;
std::array<rmq, MAX_N> rmqs;

int rmqQuery(const rmq &r, int x, int y)
{
   return std::max(r[x + (1 << log[y - x + 1]) - 1][log[y - x + 1]], r[y][log[y - x + 1]]) ;
}

template<size_t N>
std::array<int, N + 1> calculateLog()
{
    std::array<int, N + 1> l{};

    l[1] = 0;
    for(int i = 2; i <= N; i ++)
        l[i] = 1 + l[i / 2];

    return l;
}

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;
};

int main()
{
    log = calculateLog<MAX_N>();
    std::ifstream fin("plantatie.in");
    int n, m;

    fin >> n >> m;
    for(int i = 0; i < n; i ++)
    {
        for(int j = 0; j < n; j ++)
            fin >> rmqs[i][j][0];
    }

    for(int r = 0; r < n; r ++)
    {
        for(int i = 0; i < n; i ++)
            for(int j = 1; (1 << j) <= i + 1; j++)
                rmqs[r][i][j] = std::max(rmqs[r][i - (1 << (j - 1))][j - 1], rmqs[r][i][j - 1]);
    }

    std::ofstream fout("plantatie.out");
    for(; m != 0; m --)
    {
        int i, j, k;
        fin >> i >> j >> k;

        auto r = Range{i - 1, i + k - 1};
        int s = j - 1, e = j + k - 2;
        fout << std::accumulate(r.begin(), r.end(), 0, [s, e](int max, int i){
            return std::max(
                    max,
                    rmqQuery(rmqs[i], s, e)
            );
        }) << "\n";
    }

    return 0;
}