Cod sursa(job #1687944)

Utilizator VladTiberiuMihailescu Vlad Tiberiu VladTiberiu Data 13 aprilie 2016 10:04:37
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.54 kb
#include <fstream>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iomanip>

#define NMax 100005
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");

int n,m,nr,x,l,y,diff;
vector<int> G[NMax];
int euler[NMax << 1], first[NMax],viz[NMax],lg2[NMax << 1];
int rmq[20][NMax];

void dfs(int nod,int tata){
    viz[nod] = viz[tata] + 1;
    euler[++nr] = nod;
    first[nod] = nr;

    for(int i = 0; i < G[nod].size(); ++i){
        dfs(G[nod][i],nod);
        euler[++nr] = nod;
    }
}
int main()
{
    f >> n >> m;
    for(int i = 1; i < n; ++i){
        f >> x;
        G[x].push_back(i + 1);
    }
    dfs(1,0);
    lg2[1] = 0;
    for(int i = 2; i <= nr; ++i){
        lg2[i] = lg2[i / 2] + 1;
    }
    for(int i = 1; i <= nr; ++i){
        rmq[0][i] = euler[i];
    }
    for(int i = 1; (1<<i) <= nr; ++i){
        for(int j = 1; j <= nr - (1<<i) + 1; ++j){
            l = (1 << (i - 1));
            if(viz[rmq[i - 1][j]] < viz[rmq[i - 1][j + l]])
                rmq[i][j] = rmq[i - 1][j];
            else
                rmq[i][j] = rmq[i - 1][j + l];
        }
    }
    for(int i = 1; i <= m; ++i){
        f >> x >> y;
        x = first[x];
        y = first[y];
        diff = y - x + 1;
        l = lg2[diff];
        if(viz[rmq[l][x]] < viz[rmq[l][y - (1 << l) + 1]])
            g << rmq[l][x] << '\n';
        else
            g << rmq[l][y - (1 << l) + 1] << '\n';
    }
    return 0;
}