Cod sursa(job #2675257)

Utilizator Iustin01Isciuc Iustin - Constantin Iustin01 Data 21 noiembrie 2020 11:42:44
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.66 kb
#include <bits/stdc++.h>
#define MAX 100005
using namespace std;

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

struct ex{
    int e, nivel;
}v[MAX];

struct ex1{
    int valoare, poz;
}rmq[20][MAX];

int n, m, t[MAX], r, z, poz, val, x, y, minim, pozminim;
int lg[MAX];

map < int , int > hashis;
bitset < MAX > c;
stack < int > st;


void Euler(int k){
    st.push(k);
    v[++z].e = k;
    v[z].nivel = st.size() - 1;
    if(!hashis[k])
        hashis[k] = z;
    c[k] = true;
    for(int i = 1; i <= n; i++)
        if(!c[i] && t[i] == k)
            Euler(i);
    st.pop();
    if(t[k]){
        v[++z].e = t[k];
        v[z].nivel = st.size() - 1;
    }
}

int main(){
    in>>n>>m;
    for(int i = 2; i <= n; i++)
        in>>t[i];
    Euler(1);

    for(int i = 2; i <= z; i++)
        lg[i] = lg[i / 2] + 1;

    for(int j = 1; j <= z; j++)
        rmq[0][j].valoare = v[j].nivel, rmq[0][j].poz = j;

    for(int i = 1; (1 << i) <= z; i++)
    for(int j = 1; j <= z - (1 << i) + 1; j++){
        int k = (1 << (i - 1));
        if(rmq[i - 1][j].valoare < rmq[i - 1][j + k].valoare)
            rmq[i][j] = rmq[i - 1][j];
        else
            rmq[i][j] = rmq[i - 1][j + k];
    }
    while(m--){
        in>>x>>y;
        x = hashis[x], y = hashis[y];
        if(x > y)
            x ^= y, y ^= x, x ^= y;

        int dif , k, lin;
        dif = y - x + 1;
        lin = lg[dif];
        k = dif - (1 << lin);
        if(rmq[lin][x].valoare < rmq[lin][x + k].valoare)
            pozminim = rmq[lin][x].poz;
        else
            pozminim = rmq[lin][x + k].poz;

        out<<v[pozminim].e<<"\n";
    }

}