Cod sursa(job #2974653)

Utilizator matei0000Neacsu Matei matei0000 Data 4 februarie 2023 12:31:10
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.56 kb
#include <bits/stdc++.h>

using namespace std;
int poz=0,n;
int st[100005];
int dr[100005];
vector<int>fiu[100005];
pair<int,int> rmq[20][200005];

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


void build()
{
    n*=2;
    for(int i=1; i<=log2(n); i++)
    {
        for(int j=1; j<=n-(1<<i)+1; j++)
        {
            pair<int,int>a=rmq[i-1][j];
            pair<int,int>b=rmq[i-1][j+(1<<(i-1))];
            if(a.second<=b.second)
                rmq[i][j]=a;
            else
                rmq[i][j]=b;
        }
    }
}


int query(int a, int b)
{
    if(st[a]<=st[b] && dr[b]<=dr[a])
        return rmq[0][st[a]].first;
    if(st[b]<=st[a] && dr[a]<=dr[b])
        return rmq[0][st[b]].first;
    if(dr[a]<=st[b])
        a=dr[a],b=st[b];
    else
        a=st[a],b=dr[b],swap(a,b);
    int dist=log2(b-a);
    pair<int,int>x=rmq[dist][a];
    pair<int,int>y=rmq[dist][b-(1<<dist)+1];
    if(x.second<=y.second)
        return x.first;
    return y.first;
}


void euler(int nod, int grad)
{
    rmq[0][++poz].first=nod;
    rmq[0][poz].second=grad;
    st[nod]=poz;
    for(int i=0; i<fiu[nod].size(); i++)
    {
        euler(fiu[nod][i],grad+1);
        rmq[0][++poz].first=nod;
        rmq[0][poz].second=grad;
    }
    dr[nod]=poz;
    return;
}


int main()
{
    int m,a,b;
    in>>n>>m;
    for(int i=2; i<=n; i++)
    {
        in>>a;
        fiu[a].push_back(i);
    }
    euler(1,0);
    build();
    for(int i=0;i<m;i++)
    {
        in>>a>>b;
        out<<query(a,b)<<'\n';
    }
}