Cod sursa(job #2398146)

Utilizator sergiudnyTritean Sergiu sergiudny Data 5 aprilie 2019 09:15:46
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.71 kb
#include <bits/stdc++.h>
#define DM 100005
#define LOGN 20
#define pb push_back
#define INF 0x3f3f3f3f
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");

struct elm{ int nod,niv; };
int rmq[5*DM][LOGN],n,m,a,b,firstApp[DM];
vector<int>G[DM];
vector<elm>euler;

void dfs(int nod, int niv){
    if(!firstApp[nod]) firstApp[nod] = euler.size();
    euler.pb({nod,niv});
    for(auto nxt:G[nod]){
        dfs(nxt,niv+1);
        euler.pb({nod,niv});
    }
}

void createEuler(){ dfs(1,1);}

void afis(){
    for(int i=0;i<euler.size();++i) fout<<i<<" ";
    fout<<'\n';
    for(auto i:euler) fout<<i.nod<<" ";
    fout<<'\n';
    for(auto i:euler) fout<<i.niv<<" ";
    fout<<'\n';
}

void generateRMQ(){
    int sz = euler.size();
    for(int i=1;i<sz;++i)
        rmq[i][0]=i;
    for(int j=1;(1<<j)<sz;++j) for(int i=1;i<sz;++i){
        if(i+(1<<(j-1))+1 < sz){
            int dif = i+(1<<(j-1))+1;
            if(euler[rmq[i][j-1]].niv < euler[rmq[dif][j-1]].niv)
                rmq[i][j]=rmq[i][j-1];
            else rmq[i][j]=rmq[dif][j-1];
        } else {
            rmq[i][j] = rmq[i][j-1];
        }
    }

}

void getAns(int a,int b){
    int i1 = firstApp[a], i2 = firstApp[b];
    if(i1>i2) swap(i1,i2);
    int lg = log2(b-a+1), ans=0;
    int x1 = rmq[i1][lg];
    int x2 = rmq[i2-(1<<lg)+1][lg];
    if(euler[x1].niv<euler[x2].niv) fout<<euler[x1].nod;
    else fout<<euler[x2].nod;
    fout<<'\n';
}

int main()
{
    fin>>n>>m;
    for(int i=2;i<=n;++i){
        fin>>a;
        G[a].pb(i);
    }
    euler.pb({0,INF});
    createEuler();
    generateRMQ();
    while(m--){
        fin>>a>>b;
        getAns(a,b);
    }
    return 0;
}