Cod sursa(job #2983454)

Utilizator PHOSSESSEDProsie Radu-Teodor PHOSSESSED Data 22 februarie 2023 14:53:47
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.51 kb
#include<fstream>
#include<vector>
using namespace std;

ifstream cin("lca.in");
ofstream cout("lca.out");

const int NMAX = 1e5 + 1;
const int MAXLOG = 20;

int dp[MAXLOG][NMAX << 1],e[NMAX << 1],nivel[NMAX],t,prima[NMAX],loga[NMAX << 1];

vector<int> vecini[NMAX];

void dfs(int nod)
{
    e[++t] = nod; prima[nod] = t;
    for(auto it : vecini[nod])
        {
            nivel[it] = nivel[nod] + 1;
            dfs(it); e[++t] = nod;
        }
}

void build()
{
    ///dp[i][j] = nodul cu nivelul minim
    for(int i = 2; i <= t ; i++) loga[i] = loga[i >> 1] + 1;
    for(int i = 1; i <= t ; i++) dp[0][i] = e[i];
    for(int l = 1; l <= loga[t] ; l++)
        {
            for(int i = 1; i + (1 << l) - 1 <= t ; i++)
                {
                    dp[l][i] = dp[l - 1][i];
                    if(nivel[dp[l][i]] > nivel[dp[l - 1][i + (1 << (l - 1))]])
                        dp[l][i] = dp[l - 1][i + (1 << (l - 1))];
                }
        }
}

int lca(int a,int b)
{
    int st = prima[a],dr = prima[b];
    if(st > dr) swap(st,dr);
    int p = loga[dr - st + 1];
    int ans = dp[p][st],g = dp[p][dr - (1 << p) + 1];
    if(nivel[ans] > nivel[g]) ans = g;
    return ans;
}

int main()
{
    int n,q,a,b; cin >> n >> q;
    for(int i = 2; i <= n ; i++)
        {
            cin >> a;
            vecini[a].emplace_back(i);
        }

    dfs(1); build();
    while(q--)
        {
            cin >> a >> b;
            cout << lca(a,b) << '\n';
        }

}