Cod sursa(job #2359402)

Utilizator HaesteinnSabau Florin Vlad Haesteinn Data 28 februarie 2019 20:22:16
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.37 kb
#include<bits/stdc++.h>

using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
#define NMAX 100005
int n,q;
vector<int> sons[NMAX];
vector<int> tour;
int ind[NMAX];
vector<int> depth;
int rm[2*NMAX][20];

void dfs(int u,int d)
{
    ind[u]=tour.size();
    tour.push_back(u);
    depth.push_back(d);
    for(auto s:sons[u])
    {
        dfs(s,d+1);
        tour.push_back(u);
        depth.push_back(d);
    }
}

int msb(int x)
{
    int rez=0;
    while(x>0)
    {
        rez++;
        x>>=1;
    }
    return rez;
}

void precompute()
{
    for(int i=0;i<2*n-1;i++)
        rm[i][0]=i;
    for(int j=1;(1<<j)<2*n-1;j++)
    {
        for(int i=0;i+(1<<j)-1<2*n-1;i++)
        {
            int r1=rm[i][j-1];
            int r2=rm[i+(1<<(j-1))][j-1];
            rm[i][j]=(depth[r1]<depth[r2])?r1:r2;
        }
    }
}

int rmq(int a,int b)
{
    int lg=msb(b-a+1);
    lg--;
    int r1=rm[a][lg],r2=rm[b-(1<<lg)+1][lg];
    return (depth[r1]<depth[r2])?r1:r2;
}

int lca(int a,int b)
{
    a=ind[a];
    b=ind[b];
    int r=rmq(min(a,b),max(a,b));
    return tour[r];
}

int main()
{
    fin>>n>>q;
    for(int i=2;i<=n;i++)
    {
        int dad;
        fin>>dad;
        sons[dad].push_back(i);
    }

    dfs(1,1);
//    cout<<1<<endl;
    precompute();
    for(int i=0;i<q;i++)
    {

        int a,b;
        fin>>a>>b;
        fout<<lca(a,b)<<'\n';
    }
    return 0;
}