Cod sursa(job #2374922)

Utilizator DariusDCDarius Capolna DariusDC Data 7 martie 2019 21:17:58
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.94 kb

#include <iostream>

#include <fstream>

#include <vector>

#include <cmath>

#define MAX 100005

using namespace std;

ifstream fin("lca.in");

ofstream fout("lca.out");

int n, m;

vector <int> edge[MAX];

int sparse[2*MAX][25];

bool viz[MAX];

int euler[2*MAX + 1];

int nivel[2*MAX + 1];

int index;

int prima[MAX];

//sparse table

void dfs(int nod,int lvl)

{

viz[nod] = true;

index++;

euler[index] = nod;

nivel[index] = lvl;

if (prima[nod] == 0)

prima[nod] = index;

for (unsigned int i = 0; i < edge[nod].size(); i++)

{

int vecin = edge[nod][i];

if (!viz[vecin])

{

dfs(vecin, lvl+1);

index++;

euler[index] = nod;

nivel[index] = lvl;

}

}

}

void construct()

{

for (int i = 1; i <= index; i++)

sparse[i][1] = i;

for (int j = 2; (1 << (j - 1)) <= index; j++)

{

for (int i = 1; i + (1 << (j - 1)) - 1 <= index; i++)

{

if (nivel[sparse[i][j-1]] < nivel[sparse[i + (1 << (j - 2))][j-1]])

sparse[i][j] = sparse[i][j - 1];

else

sparse[i][j] = sparse[i + (1 << (j - 2))][j - 1];

}

}

/*for (int i = 1; i <= index; i++)

{

for (int j = 1; (1 << (j - 1)) <= n; j++)

{

cout << sparse[i][j] << " ";

}

cout << "\n";

}*/

}

int rmq(int a,int b)

{

if (b < a)

swap(a,b);

int l = b - a + 1;

int k = log2(l) + 1;

if(nivel[sparse[a][k]] < nivel[sparse[a + l - (1 << (k - 1))][k]] )

return sparse[a][k];

return sparse[a + l - (1 << (k - 1))][k];

}

int lca(int low, int high)

{

if (low == high)

return low;

return euler[rmq(prima[low],prima[high])];

}

int main()

{

fin >> n >> m;

for (int i = 2; i <= n; i++)

{

int x;

fin >> x;

edge[x].push_back(i);

//edge[i].push_back(x);

}

dfs(1,1);

/*for (int i = 1; i <= index; i++)

cout << euler[i] << " ";

cout << "\n";

for (int i = 1; i <= index; i++)

cout << nivel[i] << " ";

cout << "\n";

for (int i = 1; i <= n; i++)

{

cout << prima[i] << " ";

}

cout << "\n\n";*/

construct();

while (m--)

{

int low, high;

fin >> low >> high;

fout << lca(low,high) << "\n";

}

return 0;

}