Pagini recente » Cod sursa (job #432355) | Cod sursa (job #1504480) | Cod sursa (job #1991990) | Cod sursa (job #2119038) | Cod sursa (job #2354658)
#include <vector>
#include <fstream>
using namespace std;
ifstream fin ( "lca.in" );
ofstream fout ( "lca.out" );
const int MAXN = 100005;
const int MAXK = 20;
int N, M;
int euler[MAXN * 2], h[MAXN * 2], lg[MAXN * 2], pos[MAXN], last;
int rmq[MAXK][MAXN];
vector <int> Ad[MAXN];
void citire()
{
fin >> N >> M;
int x;
for( int i = 2; i <= N; ++i )
{
fin >> x;
Ad[x].push_back(i);
}
}
void Dfs( int nod, int depth )
{
euler[++last] = nod;
h[last] = depth;
pos[nod] = last;
int w;
for( int i = 0; i < Ad[nod].size(); ++i )
{
w = Ad[nod][i];
Dfs( w, depth + 1 );
euler[++last] = nod;
h[last] = depth;
}
}
void Rmq()
{
for( int i = 2; i <= last; ++i )
lg[i] = lg[i / 2] + 1;
for( int i = 1; i <= last; ++i)
rmq[0][i] = i;
for( int i = 1; (1 << i) < last; ++i )
for( int j = 1; j <= last - (1 << i); ++j )
{
int l = 1 << (i - 1);
rmq[i][j] = rmq[i - 1][j];
if(h[ rmq[i - 1][j + l] ] < h[ rmq[i][j] ] )
rmq[i][j] = rmq[i - 1][j + l];
}
}
int lca(int x, int y)
{
int diff, l, sol, sh;
int a = pos[x], b = pos[y];
if(a > b) swap( a, b );
diff = b - a + 1;
l = lg[diff];
sol = rmq[l][a];
sh = diff - ( 1 << l );
if(h[sol] > h[ rmq[l][a + sh] ] )
sol = rmq[l][a + sh];
return euler[sol];
}
int main()
{
citire();
Dfs(1, 0);
Rmq();
while(M--)
{
int x, y;
fin >> x >> y;
fout << lca(x, y) << "\n";
}
}