Cod sursa(job #2386687)

Utilizator bolovMihail Balan bolov Data 23 martie 2019 14:18:11
Problema Stramosi Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.3 kb
// https://www.infoarena.ro/problema/stramosi

#ifdef __GNUC__
#define NDEBUG
#endif

#include <algorithm>
#include <cassert>
#include <fstream>
#include <iostream>
#include <unordered_map>
#include <vector>

constexpr const char newl = '\n';

struct Ancestor
{
    int member;
    int level;
    int ancestor;
};

struct Problem
{
    int N, M;
    std::vector<int> parents;
    std::vector<Ancestor> ancestors;
    std::unordered_map<int, std::vector<std::reference_wrapper<Ancestor>>> ancestors_by_level;

    int max_level = -1;

    auto read_input()
    {
        std::ifstream in{"stramosi.in"};
        assert(in);

        in >> N >> M;
        assert(in);

        parents.resize(N + 1);

        parents[0] = 0;

        for (int i = 1; i < static_cast<int>(parents.size()); ++i)
        {
            in >> parents[i];
        }

        ancestors.resize(M);

        for (int i = 0; i < M; ++i)
        {
            Ancestor ancestor;
            in >> ancestor.member >> ancestor.level;
            assert(in);

            max_level = std::max(max_level, ancestor.level);

            ancestors[i] = ancestor;

            ancestors_by_level[ancestor.level].emplace_back(ancestors[i]);
        }
    }

    auto solve_impl()
    {
        std::vector<int> parents_at_level(parents);

        for (int level = 1; level <= max_level; ++level)
        {
            // we have all the answer for level
            for (Ancestor& ancestor : ancestors_by_level[level])
            {
                ancestor.ancestor = parents_at_level[ancestor.member];
            }

            if (level == max_level)
                break;

            // compute next level
            for (int member = 1; member <= N; ++member)
            {
                parents_at_level[member] = parents[parents_at_level[member]];
            }
        }
    }

    auto write_out()
    {
        std::ofstream out{"stramosi.out"};
        assert(out);

        for (auto& ancestor : ancestors)
        {
            out << ancestor.ancestor << newl;
            assert(out);
        }
    }

    auto solve()
    {
        read_input();
        solve_impl();
        write_out();
    }

};

int main()
{
    Problem problem;

    problem.solve();
}