Cod sursa(job #2130864)

Utilizator filip.mihalutMihalut Filip filip.mihalut Data 13 februarie 2018 23:25:09
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.58 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#define nmax 100005

using namespace std;

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

int a[20][2*nmax];
vector < int > v[nmax];
int m,n,i,j,x,t,first[nmax] , nivel[2*nmax] , nod[2*nmax] , k , poz_st,poz_dr , y;

void dfs(int x,int bloc)
{
    nivel[++m] = bloc;
    nod[m] = x;

    if(not first[x])
        first[x] = m;

    int l = v[x].size();
    for(int i = 0;i < l;i++)
        dfs(v[x][i] , bloc + 1) , nivel[++m] = bloc, nod[m] = x;
}

void rmq()
{
    for(i = 1;i <= m;i++)
        a[0][i] = i;

    n = m;
    m = log2(n);
    k = 1;

    for(i = 1;i <= m;i++)
    {
        for(j = 1;j <= n - 2*k + 1;j++)
            {
                poz_st = a[i - 1][j];
                poz_dr = a[i - 1][j + k];
                if(nivel[poz_st] < nivel[poz_dr])
                    a[i][j] = poz_st;
                else
                    a[i][j] = poz_dr;
            }
        k *= 2;
    }
}

void lca(int x,int y)
{
    int k = log2(y - x + 1);
    m = pow(2,k);
    poz_st = a[k][x];
    poz_dr = a[k][y - m + 1];

    if(nivel[poz_st] < nivel[poz_dr])
        g << nod[poz_st] << '\n';
    else g << nod[poz_dr] << '\n';
}

int main()
{
    f >> n >> t;

    for(i = 2;i <= n;i++)
    {
        f >> x;
        v[x].push_back(i);
    }

    dfs(1,0);

    rmq();

    for(i = 1;i <= t;i++)
    {
        f >> x >> y;
        if(first[x] > first[y])
            lca(first[y],first[x]);
        else lca(first[x],first[y]);
    }
    return 0;
}