Cod sursa(job #2645801)

Utilizator ursu2001Ursu Ianis-Vlad ursu2001 Data 29 august 2020 16:57:02
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.69 kb
#include <bits/stdc++.h>
using namespace std;



uint_fast32_t N, M;
vector<vector<uint_fast32_t>> tree;



template<class dataType>
class RMQ
{
private:
    uint_fast32_t N;
    uint_fast8_t K;


    vector<uint_fast8_t> log_base_2;

    void build_log_base_2()
    {
        log_base_2.resize(N + 1, 0);

        for(uint_fast32_t i = 2; i <= N; ++i)
        {
            log_base_2[i] = log_base_2[i >> 1] + 1;
        }

    }


    vector<vector<dataType>> rmq;

    void build_rqm(vector<dataType>& data)
    {
        rmq.resize(K + 1, vector<dataType>(N + 1));

        for(uint_fast32_t i = 1; i <= N; ++i)
            rmq[0][i] = data[i];

        for(uint_fast8_t k = 1; k <= K; ++k)
            for(uint_fast32_t i = 1; i <= N; ++i)
                rmq[k][i] = min(rmq[k - 1][i], rmq[k - 1][i + (1 << (k - 1))]);
    }


public:
    RMQ(vector<dataType>& data)
    {
        N = data.size();

        build_log_base_2();

        K = log_base_2[N];

        build_rqm(data);

    }


    dataType query(uint_fast32_t left, uint_fast32_t right)
    {
        if(left > right) swap(left, right);

        uint_fast8_t k = log_base_2[right - left + 1];

        return min(rmq[k][left], rmq[k][right - (1 << k) + 1]);
    }
};



vector<uint_fast32_t> euler_tour;
vector<uint_fast32_t> original_id;
vector<uint_fast32_t> first_appearance;
uint_fast32_t timer = 0;

void build_euler_tour(uint_fast32_t node, uint_fast32_t parent)
{
    uint_fast32_t new_node_id = ++timer;

    original_id[new_node_id] = node;

    euler_tour.push_back(new_node_id);


    first_appearance[node] = euler_tour.size() - 1;


    for(uint_fast32_t& child : tree[node])
    {
        if(child == parent) continue;

        build_euler_tour(child, node);

        euler_tour.push_back(new_node_id);
    }
}



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

    ios_base::sync_with_stdio(false);
    fin.tie(0);

    fin >> N >> M;

    tree.resize(N + 1, vector<uint_fast32_t>());
    original_id.resize(N + 1);
    first_appearance.resize(N + 1);

    for(uint_fast32_t node = 2; node <= N; ++node)
    {
        uint_fast32_t parent;
        fin >> parent;

        tree[parent].push_back(node);
        tree[node].push_back(parent);
    }


    euler_tour.push_back(0); //RMQ class is 1-indexed
    build_euler_tour(1, 0);


    RMQ<uint_fast32_t> rmq(euler_tour);


    for(uint_fast32_t i = 1; i <= M; ++i)
    {
        uint_fast32_t node_x, node_y;
        fin >> node_x >> node_y;

        fout << original_id[rmq.query(first_appearance[node_x], first_appearance[node_y])] << '\n';
    }
}