Cod sursa(job #2675433)

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

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

int n, m, k;
int t[MAX], h[MAX], e[MAX], lg[MAX],first[MAX], rmq[20][MAX];
bitset < MAX > c;


void Euler(int nod, int lvl){
    e[++k] = nod;
    h[k] = lvl;
    first[nod] = k;
    c[nod] = true;
    for(int i = 1; i <= n; i++)
        if(!c[i] && t[i] == nod){
            Euler(i, lvl + 1);
            h[++k] = lvl;
            e[k] = nod;
        }
}

void RMQ(){
    for(int i = 2; i <= k; i++)
        lg[i] = lg[i / 2] + 1;
    for(int j = 1; j <= k; j++)
        rmq[0][j] = j;

    for(int i = 1; (1 << i) <= k; i++)
    for(int j = 1; j <= k - (1 << i) + 1; j++){
        int col = (1 << (i - 1));
        rmq[i][j] = rmq[i - 1][j];
        if(h[rmq[i - 1][j + col]] < h[rmq[i][j]])
            rmq[i][j] = rmq[i - 1][j + col];
    }
}

int main(){
    in>>n>>m;
    for(int i = 2; i <= n; i++)
        in>>t[i];
    Euler(1, 0);
    RMQ();
    while(m--){
        int x, y;
        in>>x>>y;
        x = first[x], y = first[y];

        if(y < x)
            x ^= y, y ^= x, x ^= y;

        int dif = y - x + 1;
        int lin = lg[dif];
        int col = dif - (1 << lin);

        int minim = rmq[lin][x];

        if(h[minim] > h[rmq[lin][x + col]])
            minim = rmq[lin][x + col];

        out<<e[minim]<<"\n";
    }
}