Cod sursa(job #2386710)

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

#ifdef __GNUC__
#define NDEBUG
#endif

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

constexpr const char newl = '\n';

struct Member
{
    int id;
    int level_from_root;
    std::vector<int> ancestors;

    Member(int id, int level_from_root) : id{id}, level_from_root{level_from_root}, ancestors{} {}
    Member(int id, int level_from_root, std::vector<int>&& ancestors)
        : id{id}, level_from_root{level_from_root}, ancestors{std::move(ancestors)}
    {
    }
};

struct Problem
{
    int N, M;
    std::vector<Member> members{};

    std::ifstream in;

    auto read_input_members()
    {
        in.open("stramosi.in");
        assert(in);

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

        members.emplace_back(0, 0);

        for (int i = 1; i <= N; ++i)
        {
            int parent_id;
            in >> parent_id;
            assert(in);

            Member& parent = members[parent_id];

            std::vector<int> ancestors;
            ancestors.reserve(parent.ancestors.size() + 1);
            ancestors.insert(ancestors.begin(), parent.ancestors.begin(), parent.ancestors.end());
            ancestors.push_back(parent_id);

            members.emplace_back(i, parent.level_from_root + 1, std::move(ancestors));
        }
    }

    auto get_ancestor(int member_id, int ancestor_level)
    {
        auto& member = members[member_id];

        int ancestors_idx = static_cast<int>(member.ancestors.size() - ancestor_level);

        if (ancestors_idx <= 0)
            return 0;

        return member.ancestors[ancestors_idx];
    }
    auto solve_questions()
    {
        std::ofstream out{"stramosi.out"};
        assert(out);

        for (int i = 0; i < M; ++i)
        {
            int member_id, ancestor_level;
            in >> member_id >> ancestor_level;
            assert(in);

            int answer = get_ancestor(member_id, ancestor_level);

            out << answer << newl;
            assert(out);
        }

        in.close();
    }

    auto solve()
    {
        read_input_members();
        solve_questions();
    }
};

int main()
{
    Problem problem;

    problem.solve();
}