Pagini recente » Cod sursa (job #284696) | Cod sursa (job #2420141) | Cod sursa (job #370164) | Cod sursa (job #1898401) | Cod sursa (job #2332751)
#include <iostream>
#include <fstream>
#include <vector>
#include <math.h>
#define MAX 100001
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, m;
int nivel[2*MAX-1];
int euler[2*MAX-1];
int PrimaAp[MAX];
int k;
bool viz[MAX];
vector <int> edge[MAX];
void dfs(int nod,int lvl)
{
viz[nod] = true;
k++;
euler[k] = nod;
nivel[k] = lvl;
if (PrimaAp[nod] == 0)
PrimaAp[nod] = k;
for (unsigned int i = 0; i < edge[nod].size(); i++)
{
int vecin = edge[nod][i];
if (!viz[vecin])
{
dfs(vecin,lvl+1);
k++;
euler[k] = nod;
nivel[k] = lvl;
}
}
}
//Facem un RMQ pt vectorul PrimaAp
int sparse[2*MAX-1][45];
void ConstructSparse()
{
for (int i = 1; i <= 2*n-1; i++)
sparse[i][1] = i;
for (int j = 2; (1 << (j-1)) <= 2*n-1; j++)
{
for (int i = 1; (i + (1 << (j-1))) <= (2*n-1) + 1; 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 <= 2*n-1; i++)
{
for (int j = 1; (1 << j) <= 2*n; j++)
cout << sparse[i][j] << " ";
cout << "\n";
}*/
}
int rmq(int low,int high)
{
int l = high - low + 1;
int k = log2(l);
int a = sparse[low][k];
int b = sparse[low + l - (1 << k)][k];
if (nivel[a] < nivel[b])
return a;
else
return b;
}
int lca(int a,int b)
{
if (a == b) //cazul trivial
return a;
if (b < a)
swap(a,b);
int x = PrimaAp[a];
int y = PrimaAp[b];
return euler[rmq(x,y)];
}
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 <= 2*n-1; i++)
cout << euler[i] << " ";
cout << "\n";
for (int i = 1; i <= 2*n-1; i++)
cout << nivel[i] << " ";
cout << "\n\n";
for (int i = 1; i <= n; i++)
cout << PrimaAp[i] << " ";
cout << "\n\n\n";
*/
ConstructSparse();
while (m--)
{
int a, b;
fin >> a >> b;
fout << lca(a,b) << "\n";
}
return 0;
}