Cod sursa(job #2836767)

Utilizator florinrafiliuRafiliu Florin florinrafiliu Data 20 ianuarie 2022 20:58:54
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.76 kb
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;

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

const int maxN = 1e5 + 5;
const int INF = 1e9;
const int maxLog = 18;

struct Euler {
    int n, i;
}euler[2 * maxN];

vector <int> g[maxN];
int poz[maxN], logg[2*maxN], rmq[maxLog][2*maxN], pas = 0;
bool vizitat[maxN];

void dfs(int node, int depth) {
    vizitat[node] = true;
    euler[++pas].i = node;
    euler[pas].n = depth;

    poz[node] = pas;

    for(int to : g[node])
        if(vizitat[to] == false) {
            dfs(to, depth + 1);
            euler[++pas].i = node;
            euler[pas].n = depth;
        }
}

int main() {

    int n, q; fin >> n >> q;

    for(int i = 2; i <= n; ++i) {
        int x; fin >> x;
        g[x].push_back(i);
        g[i].push_back(x);
    }

    dfs(1, 0);

    int N = pas;

    logg[0] = logg[1] = 0;
    for(int i = 2; i <= N; ++i)
        logg[i] = logg[i/2] + 1;

    int LOG = logg[N];

    for(int i = 1; i <= N; ++i)
        rmq[0][i] = i;

    for(int step = 1; step <= LOG; ++step)
        for(int i = 1; i + (1<<step) - 1 <= N; ++i)
            if(euler[rmq[step-1][i]].n < euler[rmq[step-1][i+(1<<(step-1))]].n)
                rmq[step][i] = rmq[step-1][i];
            else
                rmq[step][i] = rmq[step-1][i+(1<<(step-1))];

    for(int i = 1; i <= q; ++i) {
        int u, v; fin >> u >> v;

        int l = min(poz[u], poz[v]);
        int r = max(poz[u], poz[v]);
        int lg = logg[r-l+1];

        if(euler[rmq[lg][l]].n < euler[rmq[lg][r-(1<<lg)] + 1].n)
            fout << euler[rmq[lg][l]].i << "\n";
        else
            fout << euler[rmq[lg][r-(1<<lg)] + 1].i << "\n";
    }

    return 0;
}