Cod sursa(job #3258497)

Utilizator andreea678Rusu Andreea-Cristina andreea678 Data 22 noiembrie 2024 20:56:40
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.83 kb
#include <bits/stdc++.h>
#define NMAX 100005
#define MMAX 2000005
#define LOGMAX 25

using namespace std;

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

int n, m, p[NMAX];
int x;
int A[MMAX][LOGMAX];

vector<vector<int>> sons;
vector<int> v;

void citeste(){ ///citesc arborele ca o lista de adiacenta a copiilor
    fin >> n >> m;
    sons.resize(n+1);
    for(int i=2; i<=n; ++i){
        fin >> x;
        sons[x].push_back(i);
    }

}
void setP(){
    for(int i=2; i<=n; ++i){
        p[i]=-1;
    }
}

void eulerTour(int nod){
    if(p[nod]==-1){ /// daca nodul nu a fost vizitat
        p[nod]=v.size(); ///p[nod] retine prima aparitie a fiecarui nod in turul Euler
    }
    v.push_back(nod);
    for (auto &son : sons[nod]){
        eulerTour(son);
        v.push_back(nod); /// v - retine turul Euler
    }
}

void init() {
    for (int i = 0; i < v.size(); ++i) {
        A[i][0] = i;
    }

    for (int j = 1; (1 << j) <= v.size(); ++j) {
        for (int i = 0; i + (1 << j) - 1 < v.size(); ++i) {
            int p1 = A[i][j - 1];
            int p2 = A[i + (1 << (j - 1))][j - 1];
            if (v[p1] <= v[p2]) {
                A[i][j] = p1;
            } else {
                A[i][j] = p2;
            }
        }
    }
}

int RMQ(int i, int j) {
    int k = log2(j - i + 1);
    if (v[A[i][k]] <= v[A[j - (1 << k) + 1][k]]) {
        return A[i][k];
    }
    return A[j - (1 << k) + 1][k];
}

void solve() {
    int a, b, ans;
    for (int i = 1; i <= m; ++i) {
        fin >> a >> b;
        if (p[a] > p[b]) {
            ans = RMQ(p[b], p[a]);
        } else {
            ans = RMQ(p[a], p[b]);
        }
        fout << v[ans] << "\n";
    }
}

int main()
{
    citeste();
    setP();
    eulerTour(1);
    init();
    solve();
    return 0;
}