Cod sursa(job #1917225)

Utilizator VladTiberiuMihailescu Vlad Tiberiu VladTiberiu Data 9 martie 2017 11:42:32
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.55 kb
#include <bits/stdc++.h>

using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");

const int NMax = 100002;
const int INF = 0x3f3f3f3f;

int n,m,x,y,c,nr;
int viz[NMax],euler[2 * NMax],first[NMax],LG[2 * NMax];
int rmq[21][NMax * 2];
vector<int> G[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){
        if(!viz[G[nod][i]]){
            dfs(G[nod][i],nod);
            euler[++nr] = nod;
        }
    }
}
int lca(int x, int y){
    x = first[x];
    y = first[y];
    if(x > y)
        swap(x,y);
    int dif = y - x + 1;
    dif = LG[dif];
    if(viz[rmq[dif][x]] < viz[rmq[dif][y - (1 << dif) + 1]]){
        return rmq[dif][x];
    }else
        return rmq[dif][y - (1 << dif) + 1];
}
int main()
{
    f >> n >> m;
    for(int i = 2; i <= n; ++i){
        f >> x;
        G[i].push_back(x);
        G[x].push_back(i);
    }
    dfs(1,0);
    LG[1] = 0;
    for(int i = 2; i <= nr; ++i)
        LG[i] = LG[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  + (1 << i) <= nr + 2; ++j){
            if(viz[rmq[i - 1][j]] < viz[rmq[i - 1][j + (1 << (i - 1))]]){
                rmq[i][j] = rmq[i - 1][j];
            }else
                rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
        }
    }

    for(int i = 1; i <= m; ++i){
        f >> x >> y;
        g << lca(x,y) << '\n';
    }

    return 0;
}