Cod sursa(job #2641209)

Utilizator OvidRata Ovidiu Ovid Data 10 august 2020 15:56:32
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.36 kb
#include<bits/stdc++.h>
using namespace std;
#define INIT  ios_base :: sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define mp make_pair
#define pb push_back
#define ft first
#define sc second
#define ll long long
#define pii pair<int, int>
#define count_bits __builtin_popcount
#define pow pw
int t, n, m, k, a[300010], q, l, r;

ifstream fin("lca.in"); ofstream fout("lca.out");
#define cin fin
#define cout fout



vector<pii> tour;
int dpt[100010];
int ft[100010];
vector<vector<int>> g;
int p[200010];
vector<pii> rmq[18];
vector<int> pow;


void euler(){
dpt[1]=1;
stack<int> s;
s.push(1);

while(!s.empty()){
    int top=s.top();

    if(ft[top]==0){
        ft[top]=((int)tour.size());
    }
    dpt[top]=dpt[p[top] ]+1;
    tour.pb(mp(dpt[top],top) );
    for(;g[top].size()>0;){
        s.push(g[top].back());
        g[top].pop_back();
        goto Next;
    }
    s.pop();

    if(p[top]!=0){
    s.push(p[top]);}
    if(ft[top]==0){
        ft[top]=((int)tour.size())-1;
    }
    Next:continue;
}


}


void RMQ(){
for(int j=0; (((int)1)<<j)<tour.size(); j++){
   rmq[j].resize(tour.size());
    for(int i=0; i<tour.size(); i++){
        if(j==0){
            rmq[j][i]=tour[i];
        }
        else{
                if( (i+( ((int)1)<<(j) ))<(tour.size()) ){
            if(rmq[j-1][i].ft<=rmq[j-1][i+(((int)1)<<(j-1)) ].ft){
                rmq[j][i]=rmq[j-1][i];
            }
            else{
                rmq[j][i]=rmq[j-1][i+(((int)1)<<(j-1) )];
            }


            }
        }
    }
}
pow.resize( (tour.size()+10) );
int temp=0;
for(int i=1; i<pow.size(); i++){
    if(i>=(((int)1)<<((int)temp+1)) ){temp++;}
    pow[i]=temp;
}



}


int LCA(int u, int v){
int x=ft[u], y=ft[v];
if(y<x){swap(x, y);}
int l=y-x;
int j=pow[l];

if(rmq[j][x].ft<=rmq[j][y-(((int)1)<<j)+1].ft){
    return rmq[j][x].sc;
}
else{
    return rmq[j][y-(((int)1)<<j)+1].sc;
}


}





int32_t main(){
INIT
cin>>n>>m;
g.resize(n+5);
for(int i=1; i<n; i++){
    cin>>p[i+1];
    g[p[i+1] ].pb(i+1);
}
euler(); RMQ();
/*for(int i=0; i<tour.size(); i++){cout<<tour[i].sc<<" ";}
cout<<"\n";*/
for(int i=1; i<=m; i++){
    int u,v;
    cin>>u>>v;
    cout<<LCA(u, v)<<"\n";
}



return 0;
}