Cod sursa(job #3263385)

Utilizator ioanabaduIoana Badu ioanabadu Data 14 decembrie 2024 11:00:44
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.24 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

ifstream in("lca.in");
ofstream out("lca.out");

int n, queries;
vector <int> graph[200005];
vector <pair <int,int>> arr;
int rmq[200005][25], idx[200005], power[200005];

void euler (int x, int predecesor, int level){
    arr.push_back({x, level});
    if (idx[x] == -1)
        idx[x] = arr.size()-1;

    for (auto idx:graph[x])
        if (idx != predecesor){
            euler(idx, x, level+1);
            arr.push_back({x, level});
        }
}

void buildRmq (){
    for (int i=0; i<arr.size(); ++i)
        rmq[i][0] = i; // tin minte indicii (am nevoie de noduri dar trebuie sa compar dupa height)

    for (int j=1; j<=18; ++j){
        for (int i=0; i<arr.size(); ++i){
            if (arr[rmq[i][j-1]].second < arr[rmq[i+(1<<(j-1))][j-1]].second) // compar dupa level
                rmq[i][j] = rmq[i][j-1];
            else
                rmq[i][j] = rmq[i+(1<<(j-1))][j-1];
        }
    }
}

void BuildPower2 (){
    power[1] = 0;
    for (int i=2; i<arr.size(); ++i){
        if (i > 1<<(power[i-1]+1)){
            power[i] = power[i-1]+1;
        }
        else
            power[i] = power[i-1];
    }
}

int query (int x, int y){
    if (arr[rmq[x][power[y-x+1]]].second < arr[rmq[y-power[y-x+1]+1][power[y-x+1]]].second)
        return arr[rmq[x][power[y-x+1]]].first;
    else
        return arr[rmq[y-power[y-x+1]+1][power[y-x+1]]].first;
}

int main (){
    int x, y;

    in >> n >> queries;
    for (int i=1; i<n; ++i){
        in >> x;

        graph[x].push_back(i+1);
        graph[i+1].push_back(x);
    }
    for (int i=1; i<=n; ++i)
        idx[i] = -1;

    euler (1, 0, 1);
    buildRmq();
    BuildPower2();

    // for (int i=0; i<arr.size(); ++i)
    //     cout << i << ' ';
    // cout << '\n';
    // for (int i=0; i<arr.size(); ++i)
    //     cout << arr[i].first << ' ';
    // cout << '\n';
    // for (int i=0; i<arr.size(); ++i)
    //     cout << arr[i].second << ' ';
    // cout << '\n';

    for (; queries; --queries){
        in >> x >> y;

        if (idx[x] > idx[y])
            swap (x,y);
        out << query(idx[x], idx[y]) << '\n';
    }

    return 0;
}