Pagini recente » Cod sursa (job #1890081) | Cod sursa (job #2954180) | Cod sursa (job #1053382) | Cod sursa (job #2480108) | Cod sursa (job #2865273)
#include <bits/stdc++.h>
#define NMAX 100005
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector<int> LA[NMAX];
int lg[2*NMAX+1];
struct varf
{
int x, lvl;
};
vector<varf> euler;
int n, m;
int first[NMAX], dp[2*NMAX][20];
void dfs(int vf, int pred, int lvl);
void rmq();
int LCA(int x, int y);
void citire();
int main()
{
int i;
citire();
lg[1]=0;
for (i=2; i<=2*NMAX; i++)
lg[i]=lg[i/2]+1;
dfs(1, 0, 0);
rmq();
for(i=1; i<=m; ++i)
{
int x, y;
fin>>x>>y;
fout<<LCA(x, y)<<'\n';
}
return 0;
}
void dfs(int vf, int pred, int lvl)
{
int i, x;
first[vf] = euler.size();
euler.push_back({vf, lvl});
for (i=0; i<LA[vf].size(); i++)
{
x=LA[vf][i];
if(x!=pred)
{
dfs(x, vf, lvl + 1);
euler.push_back({vf, lvl});
}
}
}
void rmq()
{
int i, j, val1, val2;
int n=euler.size();
for (i=1; i<=n; i++)
dp[i][0]=i;
for (j=1; (1<<j)<=n; j++)
for (i=1; i<=n-(1<<j)+1; i++)
{
val1=dp[i][j-1];
val2=dp[i+(1<<(j-1))][j-1];
if (euler[val1].lvl<euler[val2].lvl)
dp[i][j]=val1;
else dp[i][j]=val2;
}
}
int LCA(int x, int y)
{
x=first[x];
y=first[y];
if(x>y)
swap(x, y);
int len=y-x+1;
len=lg[len];
int val1=dp[x][len], val2=dp[y-(1<<len)+1][len];
if (euler[val1].lvl<euler[val2].lvl)
return euler[val1].x;
return euler[val2].x;
}
void citire()
{
fin>>n>>m;
for(int i=2; i<=n; ++i)
{
int x;
fin>>x;
LA[x].push_back(i);
LA[i].push_back(x);
}
}