Cod sursa(job #1943240)

Utilizator the.manIon Man the.man Data 28 martie 2017 14:15:42
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.41 kb
#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
ifstream fi("lca.in");
ofstream fo("lca.out");

const int dim = 100002;

int N, M, nr;
int E[2 * dim], niv[2 * dim] ; //e-reprez. euleriana
int  poz[dim];   //poz[i]=pozititia primei aparitii a noodului i in reprez. euleriana
int c[2 * dim][20];
vector < int > G[dim];


void ReadGraph()
{
fi >> N >> M;
    for(int i = 2, x; i <= N; ++i)
    {
        fi >> x;
        G[x].push_back(i);
    }
}

void ReprezEuleriana(int x, int nv)
{
    ++nr;
    E[nr] = x, niv[nr] = nv, poz[x] = nr;
    for(auto y : G[x])
    {
        ReprezEuleriana(y, nv + 1);
        ++nr;
        E[nr] = x, niv[nr] = nv;
    }
}

void RMQ()
{
    int n = 2 * N - 1;
    for(int i = 1; i <= n; ++i)  c[i][0] = i;

    for(int j = 1; (1 << j) <= n; ++j)
        for(int i = 1; i + (1 << j) - 1 <= n; ++i)
          if (niv[c[i][j - 1]] < niv[c[i + (1 << (j - 1))][j - 1]])
                  c[i][j] = c[i][j - 1];
             else c[i][j] = c[i + (1 << (j - 1))][j - 1];

}

int LCA(int x, int y)
{
    if(x > y) swap(x, y);
    int L = log2(y - x  + 1);

    if(niv[c[x][L]] < niv[c[y - (1 << L) + 1][L]]) return E[c[x][L]];
    return E[c[y - (1 << L) + 1][L]];
}

int main()
 {

    ReadGraph();
    ReprezEuleriana(1, 1);
    RMQ();

    while(M--)
        {
        int x,y;
        fi >> x >> y;
        fo << LCA(poz[x],poz[y]) << "\n";
        }


    return 0;
}