Pagini recente » Cod sursa (job #1625029) | Cod sursa (job #3126938) | Cod sursa (job #3268090) | Cod sursa (job #1162484) | Cod sursa (job #1656848)
#include <iostream>
#include <fstream>
#include <vector>
#define NMAX 100005
using namespace std;
vector<vector<int> > G;
vector<int> E, H, FirstPosition, aux, logg;
vector<vector<int> > RMQ;
int N, M;
void read();
void Euler(int node, int h);
void preprocesare();
int log2(int N);
int Query(int a, int b);
int LCA(int a, int b);
int main()
{
read();
Euler(1, 0);
preprocesare();
int a, b;
for(int i=1; i<=M; ++i) {
scanf("%d%d", &a, &b);
if(a == b)
cout<<a<<'\n';
else
cout<<LCA(a, b)<<'\n';
}
return 0;
}
int LCA(int a, int b)
{
return Query(FirstPosition[a], FirstPosition[b]);
}
int Query(int a, int b)
{
if(a > b) {
a += b;
b = a - b;
a -= b;
}
int k = logg[b-a+1];
if(H[RMQ[a][k]] < H[RMQ[b-(1<<k)][k]])
return RMQ[a][k];
else
return RMQ[b-(1<<k)][k];
}
void preprocesare()
{
logg.push_back(0);
logg.push_back(0);
logg.push_back(1);
for(int i=3, carry = 1; i<=2*E.size()+10; ++i, ++carry) {
logg.push_back(0);
logg[i] = logg[i-1];
if((carry)>>(logg[i-1]) & 1)
logg[i]++, carry = 0;
}
int maxLog = logg[E.size()-1];
aux.assign(maxLog+1, 0);
RMQ.assign(2 * E.size(), aux);
for(int i=0; i<E.size(); ++i)
RMQ[i][0] = E[i];
for(int k=1; k<=maxLog; ++k)
for(int i=0; i<E.size(); ++i)
if(H[RMQ[i][k-1]] < H[RMQ[i+(1<<(k-1))][k-1]])
RMQ[i][k] = RMQ[i][k-1];
else
RMQ[i][k] = RMQ[i+(1<<(k-1))][k-1];
}
void Euler(int node, int h)
{
E.push_back(node);
H[node] = h;
FirstPosition[node] = E.size()-1;
for(int i=0; i<G[node].size(); ++i) {
Euler(G[node][i], h+1);
E.push_back(node);
}
}
void read()
{
freopen("lca.in", "rt", stdin);
freopen("lca.out", "wt", stdout);
scanf("%d%d", &N, &M);
H.assign(N+2, 0);
FirstPosition.assign(N+2, 0);
G.assign(N+2, vector<int>());
int b;
for(int i=2; i<=N; ++i)
{
scanf("%d", &b);
G[b].push_back(i);
}
}