Pagini recente » Cod sursa (job #1473724) | Cod sursa (job #1118029) | Cod sursa (job #947892) | Cod sursa (job #1016162) | Cod sursa (job #3003295)
#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int nmax = 100000;
const int log1 = log2(nmax);
vector<int>g[nmax + 1];
int nivel[nmax + 1];
int poz[nmax + 1];
int dp[log1 + 1][nmax + 1];
vector<int>v;
int n,m;
int pozi = 0;
void dfs(int node, int level)
{
v.push_back(node);
nivel[node] = level;
level++;
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))];
}
}
int 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 l2 = log2(length);
int lint1 = (1<<l2);
int finali = 0x3f3f3f3f;
int cmp = dp[l2][pozx];
int cmp2 = dp[l2][pozy - lint1 + 1];
if(nivel[cmp] < finali)
finali = cmp;
if(nivel[cmp2] < finali)
finali = cmp2;
return finali;
}
int main()
{
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;
out<<find_ancestor(x,y)<<'\n';
}
return 0;
}