Cod sursa(job #2457901)

Utilizator alexdumitrescuDumitrescu George Alex alexdumitrescu Data 18 septembrie 2019 23:06:48
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.32 kb
#include <bits/stdc++.h>
#define Nmax 100005
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
int o[2*Nmax], a[2*Nmax], t[Nmax], l[Nmax], poz[Nmax], m[2*Nmax][20], n, q, i, j, x, y, k;
vector <int> v[Nmax];
void dfs(int x)
{
    int i;
    o[++k]=x;

   for(i=0; i<v[x].size(); i++)
    {
        l[v[x][i]]=l[x]+1;
        dfs(v[x][i]);
        o[++k]=x;
    }
}
void construieste()
{
    int i, j;
    for(i=1;i<n*2-1;i++)
        m[i][0]=i;

    for(j=1;(1<<j)<=2*n-1;j++)
        for(i=1;i+(1<<j)<=2*n-1;i++)
            if(a[m[i][j-1]]<a[m[i+(1<<(j-1))][j-1]])
                m[i][j]=m[i][j-1];
            else m[i][j]=m[i+(1<<(j-1))][j-1];

}
int rmq(int x, int y)
{
    int lg=y-x+1;
    for(k=0;(1<<(k+1))<=lg;k++);

    if(a[m[x][k]]<a[m[y-(1<<k)+1][k]])
        return m[x][k];
    return m[y-(1<<k)+1][k];
}
int main()
{
    fin >> n >> q;
    for(i=2; i<=n; i++)
    {
        fin >> t[i];
        v[t[i]].push_back(i);
    }
    dfs(1);
    for(i=1; i<=2*n-1; i++)
    {
        a[i]=l[o[i]];
        if(poz[o[i]]==0)
            poz[o[i]]=i;
    }
    construieste();
    for(i=1; i<=q; i++)
    {
        fin >> x >> y;
        if(poz[x]>poz[y])
            swap(x, y);
        fout << o[rmq(poz[x], poz[y])] << '\n';
    }
    return 0;
}