Cod sursa(job #2739819)

Utilizator MateiAruxandeiMateiStefan MateiAruxandei Data 10 aprilie 2021 11:09:53
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.87 kb
#include <bits/stdc++.h>

using namespace std;

const int INF = (1 << 30), NMAX(100005);
using VI  = vector<int>;
using VVI = vector<VI>;
using VB  = vector<bool>;

void BUNA(const string& task = "")
{
    if (!task.empty())
        freopen((task + ".in").c_str(), "r", stdin),
                freopen((task + ".out").c_str(), "w", stdout);
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
}
void PA()
{
    exit(0);
}

VI G[NMAX];
int first[2 * NMAX], lis[2 * NMAX], lvl[2 * NMAX], nr, rmq[20][4 * NMAX], n, m, put[2 * NMAX];

void DFS(int nod, int niv){
    lis[++nr] = nod;
    lvl[nr] = niv;
    first[nod] = nr;

    for(auto it: G[nod]){
        DFS(it, niv + 1);
        lis[++nr] = nod;
        lvl[nr] = niv;
    }
}

void PRECOMPUTE(){
    for(int i = 1; i <= nr; ++i)
        rmq[0][i] = i;
    int lim = log2(nr);
    for(int pt = 1; pt <= lim; ++pt)
        for(int i = 1; i <= nr - (1 << pt) ; ++i)
            if(lvl[rmq[pt - 1][i]] < lvl[rmq[pt - 1][i + (1 << (pt - 1))]])
                rmq[pt][i] = rmq[pt - 1][i];
            else rmq[pt][i] = rmq[pt - 1][i + (1 << (pt - 1))];
}

int lca(int a, int b){
    a = first[a];
    b = first[b];
    if(a > b)
        swap(a, b);
    int lg = b - a + 1;
    int fs = lvl[rmq[put[lg]][a]];
    int sc = lvl[rmq[put[lg]][a + lg - (1 << put[lg])]];
    if(fs > sc)
        return lis[rmq[put[lg]][a + lg - (1 << put[lg])]];
    return lis[rmq[put[lg]][a]];
}

int main()
{
    BUNA("lca");
    cin >> n >> m;

    for(int i = 2; i <= n; ++i){
        int y;
        cin >> y;

        G[y].push_back(i);
    }

    for(int i = 2; i <= 2 * NMAX - 5; ++i)
        put[i] = put[i / 2] + 1;

    DFS(1, 0);
    PRECOMPUTE();

    for(int i = 1; i <= m; ++i){
        int x, y;
        cin >> x >> y;

        cout << lca(x, y) << '\n';
    }
    PA();
}