Pagini recente » Cod sursa (job #1702357) | Cod sursa (job #529932) | Cod sursa (job #703047) | Cod sursa (job #2196776) | Cod sursa (job #2374420)
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#define MAX 100001
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, m;
int N = 6;
int v[10] = {0, 3, 2, 1, 7, 4, 5, 6, 69}; //doar pt a testa rmq
vector <int> edge[MAX];
int sparse[300][20];
bool viz[MAX];
int euler[2*MAX];
int nivel[2*MAX];
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 (a == b)
return nivel[prima[a]];
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)
{
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;
}