Cod sursa(job #2007877)

Utilizator MaligMamaliga cu smantana Malig Data 4 august 2017 13:43:03
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.63 kb
#include <iostream>
#include <fstream>
#include <vector>

#define ll long long
#define pb push_back
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");

const int NMax = 1e5 + 5;

int N,M,nrEuler;
int euler[2*NMax],rmq[2*NMax][20],lg[2*NMax],depth[NMax],poz[NMax];
vector<int> v[NMax];

void build(int,int);

int main() {
    in>>N>>M;
    for (int i=2;i <= N;++i) {
        int dad;
        in>>dad;

        v[dad].pb(i);
    }

    build(1,0);

    rmq[1][0] = euler[1];
    for (int i=2;i <= nrEuler;++i) {
        rmq[i][0] = euler[i];
        lg[i] = lg[i/2] + 1;
    }

    for (int p=1;(1<<p) <= nrEuler;++p) {
        for (int i=1;i + (1<<p) - 1 <= nrEuler;++i) {
            int nod1 = rmq[i][p-1], nod2 = rmq[i+(1<<(p-1))][p-1];
            if (depth[nod1] < depth[nod2]) {
                rmq[i][p] = nod1;
            }
            else {
                rmq[i][p] = nod2;
            }
        }
    }

    while (M--) {
        int x,y;
        in>>x>>y;

        x = poz[x];
        y = poz[y];
        if (x > y) {
            swap(x,y);
        }

        int pw = lg[y-x+1],
            nod1 = rmq[x][pw],
            nod2 = rmq[y - (1<<pw) + 1][pw];
        if (depth[nod1] < depth[nod2]) {
            out<<nod1<<'\n';
        }
        else {
            out<<nod2<<'\n';
        }
    }

    in.close();out.close();
    return 0;
}

void build(int node,int dad) {
    euler[++nrEuler] = node;
    poz[node] = nrEuler;
    depth[node] = depth[dad] + 1;

    for (int nxt : v[node]) {
        build(nxt,node);

        euler[++nrEuler] = node;
    }
}