Cod sursa(job #2574925)

Utilizator NashikAndrei Feodorov Nashik Data 6 martie 2020 10:42:49
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.72 kb
//#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
int euclid[200005],nv[200005],lg[2000000],put[25],cnt=0,fr[200005],rmq[25][200005];
vector<int> v[100005];
void dfs(int nod,int niv){
    euclid[++cnt]=nod;
    nv[cnt]=niv;
    for(auto u:v[nod]){
        dfs(u,niv+1);
        euclid[++cnt]=nod;
        nv[cnt]=niv;
    }
}
int ma(int a,int b){
    if(nv[a]<nv[b])
        return a;
    return b;
}
int find_lca(int a,int b){
    a=fr[a];
    b=fr[b];
    if(a>b)
        swap(a,b);
    int dist=b-a+1;
    int e=lg[dist];
    return euclid[ma(rmq[e][a],rmq[e][b-put[e]+1])];
}
int main()
{
    int n,m,a,b;
    cin>>n>>m;
    for(int i=2;i<=n;i++){
        cin>>a;
        v[a].push_back(i);
    }
    dfs(1,1);
    for(int i=1;i<=cnt;i++){
        rmq[0][i]=i;
    }
    put[0]=1;
    for(int i=1;i<=20;i++){
        put[i]=put[i-1]*2;
        lg[put[i]]++;
    }
    for(int i=1;i<=1000000;i++)
        lg[i]+=lg[i-1];
     for(int j=1;j<=18;j++){
        for(int i=1;i<=cnt;i++){
            if(i+put[j]-1>cnt)
                break;
            if(nv[rmq[j-1][i]]<nv[rmq[j-1][i+put[j-1]]]){
                rmq[j][i]=rmq[j-1][i];
            }
            else{
                rmq[j][i]=rmq[j-1][i+put[j-1]];
            }
        }
    }
    for(int i=cnt;i>=1;i--){
        fr[euclid[i]]=i;
    }
    //for(int i=1;i<=n;i++){
        //cout<<i<<" "<<fr[i]<<"\n";
    //}
    for(int i=1;i<=m;i++){
        cin>>a>>b;
        //cout<<fr[a]<<" "<<fr[b]<<"\n";
        int dist=fr[a]-fr[b]+1;
        //cout<<dist<<" "<<lg[dist]<<"\n";
        cout<<find_lca(a,b)<<"\n";
    }
    return 0;
}