Cod sursa(job #2720094)

Utilizator marius004scarlat marius marius004 Data 10 martie 2021 16:26:18
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.55 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>

using namespace std;

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

const int NMAX = 100001;

int n, m, tree[NMAX], level[NMAX], s[NMAX], dp[NMAX][32];
vector < int > G[NMAX];

//dp[node][pow2] <=> al 2^pow2 lea stramos comun al lui node

void dfs(int node, int l) {

    level[node] = l;
    s[l] = node;

    for(int e = 0;l - (1 << e) > 0;++e)
        dp[node][e] = s[l - (1 << e)];

    for(auto& it : G[node])
        dfs(it, l + 1);
}

int main() {

    f >> n >> m;

    for(int i = 2;i <= n;++i) {
        f >> tree[i];
        G[ tree[i] ].push_back(i);
    }

    dfs(1, 0);

    for(;m--;) {

        int x, y;
        f >> x >> y;

        ///aici incercam sa aducem nodurile la acelasi nivel
        if(level[x] < level[y])
            swap(x, y);

        int diff = level[x] - level[y]; /// cat trebuie sa l urcam pe x a.i sa fie la acelasi nivel cu y

        /// ca sa l aducem la acelasi nivel ne vom
        /// folosi de reprezentarea binara a lui diff
        for(int exp = 0;diff;diff >>= 1, exp++) {
            if (diff & 1)
                x = dp[x][exp];
        }

        /// daca am gasit LCA ul
        if(x == y) {
            g << x << '\n';
            continue;
        }

        //urcam
        int exp = log2(n) + 1;
        for(;tree[x] != tree[y];exp--) {
            if(dp[x][exp] != dp[y][exp] && dp[x][exp] && dp[y][exp]) {
                x = dp[x][exp];
                y = dp[y][exp];
            }
        }

        g << max(dp[x][0], 1) << '\n';
    }

    return 0;
}