Cod sursa(job #3041201)

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

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

const int logmax = 19;
constexpr int NMAX = 1e5 + 1;

vector<int> fii[NMAX];
int nivel[NMAX],euler[2 * NMAX],loga[2 * NMAX],dp[logmax][2 * NMAX],poz[NMAX],e;

void dfs(int nod)
{
    euler[++e] = nod; poz[nod] = e;
    for(auto it : fii[nod])
        {
            nivel[it] = nivel[nod] + 1;
            dfs(it); euler[++e] = nod;
        }
}


int lca(int st,int dr){

    if(st > dr) swap(st,dr);
    int l = loga[dr - st + 1]; int ans = dp[l][st];
    if(nivel[ans] > nivel[dp[l][dr - (1 << l) + 1]]) ans = dp[l][dr - (1 << l) + 1];
    return ans;
}

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

    dfs(1);
    for(int i = 1; i <= e ; i++)
        {
            if(i != 1) loga[i] = loga[i / 2] + 1;
            dp[0][i] = euler[i];
        }

    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];
                    if(nivel[dp[l][i]] > nivel[dp[l - 1][i + (1 << (l - 1))]]) dp[l][i] = dp[l - 1][i + (1 << (l - 1))];
                }
        }

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

}