Cod sursa(job #2759063)

Utilizator lahayonTester lahayon Data 15 iunie 2021 00:29:39
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.8 kb
#include <fstream>	
#include <vector>
#include <cmath>

using namespace std;

void parcurgere_euler(const vector<vector<int>>& graph, int node, int level, vector<int>& first_ap, vector<pair<int, int>>& euler){
    
    euler.push_back(make_pair(node, level));
    first_ap[node] = euler.size() - 1;

    for(auto adjacent : graph[node]){
        parcurgere_euler(graph, adjacent, level + 1, first_ap, euler);
        euler.push_back(make_pair(node, level));
    }
}

		
int main(){
	
    ifstream cin("lca.in");
    ofstream cout("lca.out");
	
    int N, M;
    cin >> N >> M;
    vector<vector<int>> graph(N, vector<int>{});
    for(int i = 1, x; i < N; ++i){
        cin >> x;
        --x;
        graph[x].push_back(i);
    }

    vector<pair<int, int>> euler;
    vector<int> first_ap(N);

    parcurgere_euler(graph, 0, 0, first_ap, euler);

    vector<vector<int>> rmq;

    N = euler.size();

    for(int i = 0; i < N; ++i){
        rmq.push_back(vector<int>((int)log2(N) + 1, 0));
        rmq[i][0] = i;
    }

    for(int j = 1; (1 << j) <= N; ++j)
        for(int i = 0; i + (1 << j) <= N; ++i)
            if(euler[rmq[i][j - 1]].second < euler[rmq[i + (1 << (j - 1))][j - 1]].second)
                rmq[i][j] = rmq[i][j - 1];
            else rmq[i][j] = rmq[i +(1 << (j - 1))][j - 1];
        
    for(int x, y; M > 0; --M){
        cin >> x >> y;

        x = first_ap[--x];
        y = first_ap[--y];
        if(x > y)
            swap(x, y);
        int log = (int)log2(y - x + 1);
        if(euler[rmq[x][log]].second < euler[rmq[y - (1 << log) + 1][log]].second)
            cout << euler[rmq[x][log]].first + 1 << "\n";
        else cout << euler[rmq[y - (1 << log) + 1][log]].first + 1 << "\n";
    }
	
    cin.close();
    cout.close();
	
    return 0;	
}