Cod sursa(job #3000172)

Utilizator PHOSSESSEDProsie Radu-Teodor PHOSSESSED Data 12 martie 2023 08:10:25
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.58 kb
#include<fstream>
#include<vector>
using namespace std;

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

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

int dp[MAXLOG][NMAX],euler[2 * NMAX],nivel[NMAX],poz[NMAX],loga[2 * NMAX],e;

vector<int> vecini[NMAX];

void dfs(int nod)
{
    euler[++e] = nod;
    poz[nod] = e;

    for(auto it : vecini[nod])
        {
            if(poz[it]) continue;
            dfs(it);
            nivel[nod] = max(nivel[nod],nivel[it] + 1);
            euler[++e] = nod;
        }
}

int lca(int a,int b)
{
    int pa = poz[a],pb = poz[b];
    if(pa > pb) swap(pa,pb);
    int p = loga[pb - pa + 1];
    int ans = dp[p][pa];
    int other = pb - (1 << p) + 1;
    if(nivel[dp[p][other]] < nivel[ans]) ans = dp[p][other];
    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); dp[0][1] = euler[1];
    for(int i = 2; i <= e ; i++)
        {
            dp[0][i] = euler[i];
            loga[i] = loga[i / 2] + 1;
        }

    for(int l = 1; l <= loga[e] ; l++)
        {
            for(int i = 1; i + (1 << l) - 1 <= e ; i++)
                {
                    dp[l][i] = dp[l - 1][i]; int other = i + (1 << (l - 1));
                    if(nivel[dp[l - 1][other]] > nivel[dp[l][i]])
                        dp[l][i] = dp[l - 1][other];
                }
        }

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