Cod sursa(job #3280411)

Utilizator Alex_DumitrascuAlex Dumitrascu Alex_Dumitrascu Data 26 februarie 2025 13:56:37
Problema Lowest Common Ancestor Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.81 kb
#include <bits/stdc++.h>

using namespace std;

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

int lca[20][100005];
int lg2[100005];
int level[100005];

void find_level (int nod) {
    int tata = lca[0][nod];
    if (tata == 0) return;  // Avoid accessing invalid index
    if (level[tata] == 0) {
        find_level(tata);
    }
    level[nod] = level[tata] + 1;
}


int main()
{
    fin.tie(0); fin.sync_with_stdio(false);
    int n, m; fin>>n>>m;
    for (int i=2; i<=n; i++) lg2[i]=lg2[i/2]+1;
    for (int i=2; i<=n; i++) fin>>lca[0][i];
    for (int i=1; i<=lg2[n]; i++) {
        for (int j=1; j<=n; j++) {
            lca[i][j]=lca[i-1][lca[i-1][j]];
        }
    }
    level[1]=1;
    for (int i=2; i<=n; i++) find_level(i);
    int x, y;
    while (m--) {
        fin>>x>>y;
        int nivel_x = level[x], nivel_y = level[y];
        if (nivel_y>nivel_x) { // nivel_x va fi cel mai mare
            swap(x, y);
            swap(nivel_x, nivel_y);
        }
        // cout<<x<<' '<<y<<endl;
        int diff = nivel_x - nivel_y;
        while (diff!=0) {
            int linie = lg2[diff];
            x = lca[linie][x];
            diff = diff - (1<<lg2[diff]);
        }
        // cout << x << ' '<<y<<endl<<endl;
        nivel_x = nivel_y; // Avem ambele noduri la acelasi nivel
        if (x == y) { // Poate am ajuns deja la lca, (un nod este deasupra celuilalt in lantul spre radacina)
            fout << x <<'\n';
            continue;
        }
        for (int i = lg2[nivel_x]; i>=0; i--) {
            int linie = lg2[i];
            if (lca[linie][x]!=lca[linie][y]) {
                x = lca[linie][x];
                y = lca[linie][y];
                nivel_x = level[nivel_x];
                nivel_y = level[nivel_y];
            }
        }
        int ans = lca[0][x];
        fout<<ans<<'\n';
    }
    return 0;
}