Pagini recente » Arhiva de probleme | Solutii Summer Challenge, Runda 2 | Autentificare | Cod sursa (job #2013913) | Cod sursa (job #1482271)
#include <bits/stdc++.h>
using namespace std;
const int lgmax = 20;
const int nmax = 100000 + 10;
ifstream fin("lca.in");
ofstream fout("lca.out");
#define cin fin
#define cout fout
int n , q , cnt , x , y , i , j;
int L[nmax] , lg[2 * nmax] , d[nmax] , pe[4 * nmax];
int rmq[lgmax][4 * nmax];
vector < int > g[nmax];
void df(int x , int f)
{
d[x] = d[f] + 1;
pe[++cnt] = x;
L[x] = cnt;
for (auto j = g[x].begin() ; j != g[x].end() ;++j)
{
df(*j , x);
pe[++cnt] = x;
}
}
int lca(int x , int y)
{
x = L[x] , y = L[y];
if (x > y) swap(x , y);
int k = lg[y - x + 1];
int wx = rmq[k][x] , wy = rmq[k][y - (1 << k) + 1];
int res;
if (d[pe[wx]] > d[pe[wy]]) res = pe[wy];
else res = pe[wx];
return res;
}
void dormq()
{
for (i = 2 ; i <= cnt ; ++i)
lg[i] = lg[i / 2] + 1;
for (i = 1 ; i <= cnt ; ++i)
rmq[0][i] = i;
for (i = 1 ; (1 << i) <= cnt ; ++i)
for (j = 1 ; j <= cnt - (1 << i) + 1 ; ++j)
{
if (d[pe[rmq[i - 1][j]]] < d[pe[rmq[i - 1][j + (1 << (i - 1))]]])
rmq[i][j] = rmq[i - 1][j];
else rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
}
}
int main()
{
cin >> n >> q;
for (i = 2 ; i <= n ; ++i)
{
cin >> x;
g[x].push_back(i);
}
df(1 , 0);
dormq();
for (i = 1 ; i <= q ; ++i)
{
cin >> x >> y;
cout << lca(x , y) << '\n';
}
return 0;
}