Pagini recente » Cod sursa (job #2418518) | Cod sursa (job #1665968) | Cod sursa (job #1760344) | Cod sursa (job #2001672) | Cod sursa (job #2535940)
#include <fstream>
#include <vector>
#define pb push_back
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int uz[100005], n, m,nivk,poz[100005],M[100005][20];
vector <int> L[100005], v,niv;
void Euler(int k)
{
uz[k] = 1;
v.pb(k);
poz[k] = v.size() - 1;
niv.pb(nivk);
for (int i = 0; i < L[k].size(); i++)
if (!uz[L[k][i]])
{
nivk++;
Euler(L[k][i]);
nivk--;
v.pb(k);
niv.pb(nivk);
}
}
void rmq()
{
int i, j, k;
for (i = 0; i < niv.size(); i++)
M[i][0] = i;
for (k = 0; (1 << (k + 1)) <= niv.size(); k++);
for (j = 1; j <= k; j++)
for (i = 0; i < niv.size(); i++)
if (niv[M[i][j - 1]] < niv[M[i + (1 << (j - 1))][j - 1]])
M[i][j] = M[i][j - 1];
else M[i][j] = M[i + (1 << (j - 1))][j - 1];
}
int lca(int x, int y)
{
int st = poz[x], dr = poz[y],k;
if (st > dr) swap(st, dr);
for (k = 0; (1 << (k + 1)) <= dr-st+1; k++);
int poz1 = M[st][k], poz2 = M[dr - (1 << k) + 1][k];
if (niv[poz1] < niv[poz2])
return v[poz1];
else return v[poz2];
}
int main()
{
int i, x,y;
fin >> n >> m;
for (i = 2; i <=n; i++)
{
fin >> x;
L[x].pb(i);
L[i].pb(x);
}
Euler(1);
rmq();
for (i = 1; i <= m; i++)
{
fin >> x >> y;
fout<<lca(x, y)<<'\n';
}
return 0;
}