Cod sursa(job #3211648)

Utilizator Robert_MitriRobert Mitri Robert_Mitri Data 9 martie 2024 19:12:41
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.38 kb
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");

const int nmax = 100000;

vector <int> v[nmax + 5];
int lv[nmax + 5];
int fr[nmax + 5];
int eu[nmax*2 + 5];
int k;
int o;
int r[17][nmax*2+5];
int E[nmax * 2 + 5];

int n,m;

void dfs(int nod,int t=0)
{
    lv[nod]=lv[t]+1;
    eu[++k]=nod;
    fr[nod]=k;
    r[0][k]=nod;

    for(auto& i : v[nod])
        if(i!=t)
        {
            dfs(i,nod);
            eu[++k]=nod;
            r[0][k]=nod;
        }
}
void precalc()
{
    for(int i=2; i<=k; i++)
        E[i]=E[i/2]+1;
    for(int i=1; (1<<i)<=k; i++)
        for(int j=1; j<=k; j++)
        {
            r[i][j]=r[i-1][j];
            if(j+(1<<(i-1))<=k && lv[r[i-1][j+(1<<(i-1))]] < lv[r[i][j]])
                r[i][j]=r[i-1][j+(1<<(i-1))];
        }
}

int lca(int x,int y)
{
    if(fr[x]>fr[y])
        swap(x,y);
    int diff = fr[y]-fr[x]+1;
    int e = E[diff];
    if(lv[r[e][fr[x]]] < lv[r[e][fr[y]-(1<<e)+1]])
        return r[e][fr[x]];
    return r[e][fr[y]-(1<<e)+1];
}

int main()
{
    fin>>n>>m;
    for(int i=2; i<=n; i++)
    {
        int t;
        fin>>t;
        v[t].push_back(i);
    }
    dfs(1);
    precalc();
    for(int i=1; i<=m; i++)
    {
        int a,b;
        fin>>a>>b;
        fout<<lca(a,b)<<'\n';
    }
}