Pagini recente » Cod sursa (job #3135341) | Cod sursa (job #315789) | Cod sursa (job #294452) | Cod sursa (job #91126) | Cod sursa (job #2329697)
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#define MAX 100001
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector <int> edge[MAX];
int n, m;
//radacin este 1
int k;
bool viz[MAX];
int euler[2*MAX-1]; //parcurgerea euleriana
int level[2*MAX-1]; //nivelul fiecarul element din euler
int fai[MAX]; // prima aparitire a fiecarui nod in euler;
//pentru rmq
int sparse[MAX][20];
void construct()
{
for (int i = 0; i < 2*n-1; i++)
sparse[i][0] = i+1;
for (int j = 1; (1 << j) <= 2*n-1; j++)
{
for (int i = 0; (i + (1 << j) - 1) < 2*n-1; i++)
{
if (level[sparse[i][j-1]] < level[sparse[i+ (1 << (j-1))][j-1]])
sparse[i][j] = sparse[i][j-1];
else
sparse[i][j] = sparse[i+(1 << (j-1))][j-1];
//sparse[i][j] = min(level[sparse[i][j-1]],level[sparse[i+(1 << (j-1))][j-1]]);
}
}
/*for (int i = 0; i < 2*n-1; i++)
{
for (int j = 0; j < log2(2*n-1); j++)
cout << sparse[i][j] << " ";
cout << "\n";
}
cout << "\n";*/
}
int rmq(int low,int high)
{
low--;
high--;
int l = (high - low + 1);
int k = log2(l);
return min(sparse[low][k],sparse[high - (1 << k) + 1][k]);
}
void dfs(int nod,int nivel)
{
viz[nod] = true;
k++;
euler[k] = nod;
level[k] = nivel;
if (fai[nod] == 0)
fai[nod] = k;
for (unsigned int i = 0; i < edge[nod].size(); i++)
{
int vecin = edge[nod][i];
if (!viz[vecin])
{
dfs(vecin,nivel+1);
k++;
euler[k] = nod;
level[k] = nivel;
}
}
}
int lca(int a,int b)
{
if (a == b) //cazul trivial
return a;
if (fai[a] > fai[b])
swap(a,b);
return euler[rmq(fai[a],fai[b])];
}
int main()
{
fin >> n >> m;
for (int i = 1; i < n; i++)
{
int x;
fin >> x;
edge[i+1].push_back(x);
edge[x].push_back(i+1);
}
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 << level[i] << " ";
cout << "\n";
for (int i = 1; i <= n;++i)
cout << fai[i] << " ";*/
construct();
while (m--)
{
int a, b;
fin >> a >> b;
fout << lca(a,b) << "\n";
}
return 0;
}