Cod sursa(job #3213545)

Utilizator AlfexAlex Florea Alfex Data 13 martie 2024 11:34:37
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2 kb
#include <bits/stdc++.h>

#define NMAX 100001

using namespace std;

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

int n, m, k, lk;
vector<int> vecini[NMAX];
vector<int> par, first, depth;
vector<bool> viz;
vector< vector<int> > mini;

void parcurgereEul(int nod, int d){
    par.push_back(nod);
    depth.push_back(d);
    first[nod] = par.size() - 1;
    viz[nod] = true;
    for(auto vecin : vecini[nod])
        if(!viz[vecin]){
            parcurgereEul(vecin, d + 1);
            par.push_back(nod);
            depth.push_back(d);
        }
}

void check(){
    for(int i = 1; i <= n; i ++)
        g << first[i] << " ";
}

void createRmq(){
    for(int i = 0; i < k; i ++)
        mini[i][0] = i;
    for(int len = 1; len <= lk; len ++){
        for(int st = 0; st + (1 << len) - 1 < k; st ++){
            int dr = st + (1 << len) - 1;
            int mid = (st + dr) / 2 + 1;
            if(depth[mini[st][len - 1]] < depth[mini[mid][len - 1]])
                mini[st][len] = mini[st][len - 1];
            else mini[st][len] = mini[mid][len - 1];
        }
    }
}

int sol(int st, int dr){
    int len = (dr - st + 1);
    int lenL = log2(len);
    int i = st;
    int j = dr - (1 << lenL) + 1;
    if(depth[mini[i][lenL]] < depth[mini[j][lenL]])
        return par[mini[i][lenL]];
    else return par[mini[j][lenL]];
}

int main()
{
    f >> n >> m;
    for(int i = 1; i <= n - 1; i ++){
        int x;
        f >> x;
        vecini[x].push_back(i + 1);
        vecini[i + 1].push_back(x);
    }
    viz = vector<bool>(n + 1, false);
    first = vector<int>(n + 1, 0);
    parcurgereEul(1, 0);

    //check();

    k = par.size();
    lk = log2(k);
    mini = vector< vector<int> >(k, vector<int>(lk + 1));
    createRmq();

   for(int i = 1; i <= m; i ++){
        int x, y;
        f >> x >> y;
        int st = first[x];
        int dr = first[y];
        if(st > dr) swap(st, dr);
        g << sol(st, dr) << '\n';
    }
    return 0;
}