Pagini recente » Cod sursa (job #890686) | Cod sursa (job #1875449) | Cod sursa (job #3133549) | Cod sursa (job #1323519) | Cod sursa (job #2865250)
#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];
struct varf
{
int x, lvl;
};
vector<varf> euler;
vector<int> first(NMAX);
vector<vector<int>> dp(NMAX * 2, vector<int> (20, 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;
}
/*for(int i = 0; i < n; ++i)
{
rmq[i][0] = i;
}
for(int i = 1; (1 << i) <= n; ++i)
{
for(int j = 0; j + (1 << i) - 1 < n; ++j)
{
int k = rmq[j][i - 1];
int l = rmq[j + (1 << (i - 1))][i - 1];
if(euler[k].lvl < euler[l].lvl)
{
rmq[j][i] = k;
}
else
{
rmq[j][i] = l;
}
}
}*/
}
int findLCA(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;
/*int len = lg[y - x + 1];
int k = rmq[x][len];
int l = rmq[y - (1 << len) + 1][len];
if(euler[k].lvl < euler[l].lvl)
{
return euler[k].x;
}
return euler[l].x;*/
}
int main()
{
int i;
lg[1]=0;
for (i=2; i<=2*NMAX; i++)
lg[i]=lg[i/2]+1;
int n, m;
fin >> n >> m;
for(int i = 2; i <= n; ++i)
{
int x;
fin >> x;
LA[x].push_back(i);
LA[i].push_back(x);
}
dfs(1, 0, 0);
rmq();
for(int i = 1; i <= m; ++i)
{
int x, y;
fin >> x >> y;
fout << findLCA(x, y) << '\n';
}
return 0;
}