Cod sursa(job #3000954)

Utilizator VladPislaruPislaru Vlad Rares VladPislaru Data 13 martie 2023 09:14:58
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.88 kb
#include <bits/stdc++.h>

using namespace std;

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

int n, q, a[200005];
int in[200005], out[200005];
int aint[1600005];
int timer = 0;
int level[200005], euler[400005];
vector <int> adj[200005];

void DFS (int nod, int father, int lv) {
    in[nod] = ++timer;
    euler[timer] = nod;
    level[nod] = lv;
    for (int i : adj[nod])
        if (i != father) {
            DFS(i, nod, lv + 1);
            euler[timer] = nod;
        }
    out[nod] = ++timer;
}


int Query(int nod, int st, int dr, int x, int y) {
    if (st == x && dr == y) {
        return aint[nod];
    }
    int mid = (st + dr) / 2;
    if (y <= mid)
        return Query(2 * nod, st, mid, x, y);
    if (x > mid)
        return Query(2 * nod + 1, mid + 1, dr, x, y);
    int val1 = Query(2 * nod, st, mid, x, mid);
    int val2 = Query(2 * nod + 1, mid + 1, dr, mid + 1, y);
    if (level[val1] < level[val2])
        return val1;
    return val2;
}

void Build(int nod, int st, int dr) {
    if (st == dr) {
        aint[nod] = euler[st];
        return;
    }
    int mid = (st + dr) / 2;
    Build(2 * nod, st, mid);
    Build(2 * nod + 1, mid + 1, dr);
    if (level[aint[2 * nod]] < level[aint[2 * nod + 1]])
        aint[nod] = aint[2 * nod];
    else aint[nod] = aint[2 * nod + 1];
}


int main()
{
    //ios_base::sync_with_stdio(0);
    fin >> n >> q;
    for (int i = 2; i <= n; i++) {
        int x, y;
        fin >> x;
        adj[x].push_back(i);
        adj[i].push_back(x);
    }
    DFS(1, 0, 0);
    Build(1, 1, 2 * n);
    while(q--) {
        int x, y;
        fin >> x >> y;
        if (in[x] > in[y])
            swap(x, y);
        ///cout << level[x] + level[y] - 2 * level[Query(1, 1, 2 * n, in[x], in[y])] << "\n";
        fout << Query(1, 1, 2 * n, in[x], in[y]) << "\n";
    }
    return 0;
}