Cod sursa(job #3170115)

Utilizator paaull69Ion Paul paaull69 Data 16 noiembrie 2023 20:12:04
Problema Lowest Common Ancestor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.39 kb
#include <bits/stdc++.h>

using namespace std;
typedef long long int ll;
#define MOD 1000000007

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

struct rmqs
{
    int n,d;
} rmq[22][100001];

int p[100001];
vector<int> arb[100001];
int e[100001];
int cnt;

void dfs(int n,int d)
{
    rmq[0][++cnt]={n,d};
    p[n]=cnt;
    for(auto i : arb[n])
    {
        dfs(i,d+1);
        rmq[0][++cnt]={n,d};
    }
}

int lca(int x,int y)
{
    x=p[x],y=p[y];
    if(x > y)swap(x,y);
    int len = e[y-x+1];

    rmqs st=rmq[len][x];
    rmqs dr=rmq[len][y-(1<<len)+1];
    if(st.d < dr.d)return st.n;
    else return dr.n;
}
int main()
{
    int n,q;
    fin >> n >> q;
    for(int i=2;i<=n;i++)
    {
        int x;
        fin >> x;
        arb[x].push_back(i);
    }
    e[1]=0;
    for(int i=2;i<=100000;i++)e[i]=e[i/2]+1;
    dfs(1,1);
    for(int i=1;(1<<i) <= cnt;i++)
    {
        for(int j=1;j<=cnt;j++)
        {
            rmqs st = rmq[i-1][j];
            if(j+(1<<(i-1)) <= cnt)
            {
                // 1 2 3 4 5 6 7 8
                rmqs dr = rmq[i-1][j+(1<<(i-1))];
                rmq[i][j]= st.d < dr.d ? st : dr;
            }
            else
            {
                rmq[i][j]= st;
            }
        }
    }
    while(q--)
    {
        int x,y;
        fin >> x >> y;
        fout << lca(x,y) << "\n";
    }

}