Cod sursa(job #2645930)

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

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


class RMQ
{
    int N, K;
    vector<vector<int>> rmq;

public:
    RMQ(vector<int>& data)
    {
        N = data.size() - 1;
        K = log2(N);

        rmq.resize(K + 1, vector<int>(N + 1));

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

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


    int query(int left, int right)
    {
        if(left > right) swap(left, right);

        int k = log2(right - left + 1);

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


vector<int> flat_tree;
vector<int> old_id;
vector<int> first;

int timer = 0;

void tree_flattering(int node, int parent)
{
    int new_id = ++timer;

    old_id[new_id] = node;

    flat_tree.push_back(new_id);

    first[node] = flat_tree.size() - 1;


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

        tree_flattering(child, node);

        flat_tree.push_back(new_id);
    }
}



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

    fin >> N >> M;

    tree.resize(N + 1, vector<int>());
    old_id.resize(N + 1);
    first.resize(N + 1);
    flat_tree.push_back(-1);

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

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

    tree_flattering(1, -1);

    RMQ rmq(flat_tree);

    for(int i = 1; i <= M; ++i)
    {
        int x, y;
        fin >> x >> y;

        fout << old_id[rmq.query(first[x], first[y])] << '\n';
    }
}