Cod sursa(job #2775941)

Utilizator francescom_481francesco martinut francescom_481 Data 18 septembrie 2021 11:01:55
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.54 kb
#include<bits/stdc++.h>

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");
#define cin fin
#define cout fout

#define N 1000005
vector < vector < int > > gr;
int rmq[23][N], lung[N], v[N], level[N], app[N], n, x, y, k;


void euler(int nod,int lv)
{
    v[++v[0]] = nod;
    if(app[nod] == 0)app[nod] = v[0];
    level[v[0]] = lv;
    for(int i = 0 ; i < gr[nod].size() ; i++)
    {
        euler(gr[nod][i],lv+1);
        v[++v[0]] = nod;
        level[v[0]] = lv;
    }
}

int main()
{
    cin >> n >> k;
    gr.resize(n+1);
    for(int i = 2 ; i <= n ; i++)
    {
        cin >> x;
        gr[x].push_back(i);
    }
    euler(1,0);

    for(int i = 1 ; i <= v[0] ; i++)
    {
        rmq[0][i] = i;
    }
    lung[1] = 0;
    for(int i = 2 ; i <= v[0] ; i++)
    {
        lung[i] = lung[i/2]+1;
    }
    for(int i = 1 , nr = 2; nr <= v[0] ; i++, nr <<= 1)
    {
        for(int j = 1 ; j <= v[0]-nr+1 ; j++)
        {
            if(level[rmq[i-1][j]] < level[rmq[i-1][j+nr/2]])
            {
                rmq[i][j] = rmq[i-1][j];
            }
            else
            {
                rmq[i][j] = rmq[i-1][j+nr/2];
            }
        }
    }
    for( ; k ; k--)
    {
        cin >> x >> y;
        x = app[x] , y = app[y];
        if(y < x)swap(x,y);
        int d = y-x+1;
        int l = lung[d];
        int s = rmq[l][x];
        int p = y - (1 << l) + 1;
        if(level[s] < level[rmq[l][p]])s = rmq[l][p];
        cout << v[s] << '\n';
    }
    return 0;
}