Pagini recente » Cod sursa (job #149169) | Cod sursa (job #1202670) | Cod sursa (job #310712) | Cod sursa (job #211004) | Cod sursa (job #3003799)
#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int nmax = 1e5;
vector<int>g[nmax + 1];
vector<int>v;
int poz[nmax + 1];
int nivel[nmax + 1];
int dp[18][2*nmax + 1];
int pozi = 0;
void dfs(int node,int level)
{
nivel[node] = level;
level++;
v.push_back(node);
pozi++;
poz[node] = pozi;
for(int i = 0; i < g[node].size(); i++)
{
int vecin = g[node][i];
if(nivel[vecin] == 0)
{
dfs(vecin,level);
pozi++;
}
v.push_back(node);
poz[node] = pozi;
}
}
void build_rmq()
{
for(int i = 0; i < v.size(); i++)
dp[0][i] = v[i];
int length = v.size();
int l2 = log2(length);
for(int i = 1; i <= l2; i++)
for(int j = 1; j <= length; j++)
{
if(nivel[dp[i - 1][j]] < nivel[dp[i - 1][j + (1<<(i - 1))]])
dp[i][j] = dp[i - 1][j];
else
dp[i][j] = dp[i - 1][j + (1<<(i - 1))];
}
}
void find_ancestor(int x, int y)
{
int pozx = poz[x] - 1;
int pozy = poz[y] - 1;
if(pozx > pozy)
swap(pozx, pozy);
int length = pozy - pozx + 1;
int exp = log2(length);
int lint1 = (1<<exp);
int cmp = dp[exp][pozx];
int cmp2 = dp[exp][pozy - lint1 + 1];
int finali = 0x3f3f3f3f;
if(nivel[cmp] < finali)
finali = cmp;
if(nivel[cmp2] < nivel[finali])
finali = cmp2;
out<<finali<<'\n';
}
int main()
{
int n,m;
in>>n>>m;
for(int i = 1; i <= n - 1; i++)
{
int x;
in>>x;
g[x].push_back(i + 1);
}
dfs(1,1);
build_rmq();
for(int i = 1; i <= m; i++)
{
int x,y;
in>>x>>y;
find_ancestor(x,y);
}
return 0;
}