Cod sursa(job #2674619)

Utilizator Iustin01Isciuc Iustin - Constantin Iustin01 Data 19 noiembrie 2020 18:27:58
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.11 kb
#include <bits/stdc++.h>
#define MAX 100005
#define NMAX 400100
using namespace std;

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

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

struct ex2{
    int valoare = (1 << 30), p ;
}AI[NMAX];


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

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


void update(int nod, int st, int dr){
    if(st == dr){
        AI[nod].valoare = val;
        AI[nod].p = poz;
        return;
    }
    int mij = (st + dr) / 2;
    if(poz <= mij)
        update(2 * nod, st, mij);
    else
        update(2 * nod + 1, mij + 1, dr);
    if(AI[2 * nod].valoare < AI[2 * nod + 1].valoare)
        AI[nod].valoare  = AI[2 * nod].valoare, AI[nod].p = AI[2 * nod].p;
    else
        AI[nod].valoare  = AI[2 * nod + 1].valoare, AI[nod].p = AI[2 * nod + 1].p;
}

void query(int nod, int st, int dr){
    if(x <= st && dr <= y){
        if(minim > AI[nod].valoare)
            minim = AI[nod].valoare, pozminim = AI[nod].p;
        return;
    }
    int mij = (st + dr) / 2;
    if(x <= mij)
        query(2 * nod, st, mij);
    if(mij < y)
        query(2 * nod + 1, mij + 1, dr);
}

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 = 1; i <= z; i++){
        poz = i, val = v[i].nivel;
        update(1, 1, z);
    }
    while(m){
        in>>x>>y;
        x = hashis[x], y = hashis[y];
        minim = (1 << 30);
        pozminim = 0;
        query(1, 1, z);
        if(pozminim)
            out<<v[pozminim].e<<"\n";
        else{
            if(v[x].nivel < v[y].nivel)
                out<<v[x].e<<"\n";
            else
                out<<v[y].e<<"\n";
        }
        m--;
    }
}