Cod sursa(job #3226218)

Utilizator Simon2712Simon Slanina Simon2712 Data 20 aprilie 2024 17:45:39
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.49 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int N=1e5+1;
struct ura{
    int tata;
    vector<int> fii;
} v[N];
int euler[2*N];
int lg[2*N];
int rmq[2*N][19];
int vc[2*N];
int niv[N];
int m=0,n;
void eulerinho(int nod)
{
    m++;
    niv[nod]=niv[v[nod].tata]+1;
    euler[m]=nod;
    vc[nod]=m;
    for(int i=0;i<v[nod].fii.size();i++)
    {
        int nod2=v[nod].fii[i];
        eulerinho(nod2);
        m++;
        euler[m]=nod;
    }
}
void makermq(){
    int i,j,k;
    for(i=2;i<=m;i++)
        lg[i]=lg[(i>>1)]+1;
    for(i=1;i<=m;i++)
        rmq[i][0]=euler[i];
    for(j=1;(1<<j)<=m;j++)
    for(i=1;i+(1<<j)-1<=m;i++)
    {
        k=(1<<(j-1));
        if(niv[rmq[i][j-1]]<niv[rmq[i+k][j-1]])
            rmq[i][j]=rmq[i][j-1];
        else
            rmq[i][j]=rmq[i+k][j-1];
    }
}
int main()
{
    int i,x,y,a,b,j,niv1,niv2,l,q;
    fin>>n>>q;
    for(i=2;i<=n;i++)
    {
        fin>>x;
        v[i].tata=x;
        v[x].fii.push_back(i);
    }
    eulerinho(1);
    makermq();
    while(q--)
    {
        fin>>x>>y;
        a=vc[x];///unde se gasesc x si y in
        b=vc[y];///parcurgerea euler
        if(a>b)
            swap(a,b);
        l=lg[b-a+1];
        niv1=niv[rmq[a][l]];
        niv2=niv[rmq[b-(1<<l)+1][l]];
        if(niv1<niv2)
            fout<<rmq[a][l];
        else
            fout<<rmq[b-(1<<l)+1][l];
        fout<<'\n';
    }
    return 0;
}