Cod sursa(job #3205236)

Utilizator mariusdinsoreanDinsorean Marius mariusdinsorean Data 19 februarie 2024 09:39:45
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.43 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <set>
#include <tuple>
#include <vector>


using namespace std;

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

const int N = 1e5 + 4, LOG = 17;
int n, m;
int depth[N], up[N][LOG];
vector <int> v[N];

void binarylifting(int nod){
    for(auto nodnou : v[nod]){
        if(depth[nodnou] == 0){
            depth[nodnou] = depth[nod] + 1;
            up[nodnou][0] = nod;
            for(int j = 1; j < LOG; j++){
                up[nodnou][j] = up[up[nodnou][j - 1]][j - 1];
            }
            binarylifting(nodnou);
        }
    }
}

int LCA(int nod1, int nod2){
    if(depth[nod1] < depth[nod2]) swap(nod1, nod2);
    int len = depth[nod1] - depth[nod2];
    for(int j = LOG - 1; j >= 0; j--){
        if(len >= (1 << j)){
            nod1 = up[nod1][j];
            len -= (1 << j);
        }
    }
    if(nod1 == nod2) return nod1;
    for(int j = LOG - 1; j >= 0; j--){
        if(up[nod1][j] != up[nod2][j]){
            nod1 = up[nod1][j];
            nod2 = up[nod2][j];
        }
    }
    return up[nod1][0];
}

int main()
{
    fin >> n >> m;
    for(int i = 2; i <= n; i++){
        int nod;
        fin >> nod;
        v[nod].push_back(i);
    }

    binarylifting(1);

    while(m--){
        int nod1, nod2;
        fin >> nod1 >> nod2;
        fout << LCA(nod1, nod2) << "\n";
    }
    return 0;
}