Pagini recente » Cod sursa (job #32686) | Cod sursa (job #3194423) | Cod sursa (job #652695) | Cod sursa (job #2195178) | Cod sursa (job #2635199)
#include <fstream>
#include <vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
int n ,q, viz[100001];
int v[100001], k, a;
int rmq[200001][20];
int euler[200001], nivel[200001], poz[100001];
vector <int> L[100001];
void dfs(int x)
{
a++;
viz[x] = 1;
euler[++k] = x;
nivel[k] = a;
if(!poz[x])
poz[x] = k;
for(int i : L[x])
{ if(!viz[i])
{
dfs(i);
euler[++k] = x;
nivel[k] = a;
}
}
a--;
}
void prelucrare();
int LCA(int,int);
int queryRMQ(int i ,int j)
{
int length = j - i + 1;
int log = 0;
while( (1<<(log + 1)) <= length)
log++;
if(nivel[rmq[i][log]] < nivel[rmq[j - (1<< log) + 1][log]])
return euler[rmq[i][log]];
else
return euler[rmq[j -(1 << log) + 1][log]];
}
int main() {
cin >> n >> q;
for(int i =2;i <= n ;i ++)
{
cin >> v[i];
L[i].push_back(v[i]);
L[v[i]].push_back(i);
}
dfs(1);
prelucrare();
int x, y;
while(q--)
{
cin >> x >> y;
cout << LCA(x,y)<<'\n';
}
// for(int i = 1 ;i <=k ;i ++)
// cout << euler[i] << " " << nivel[i]<<'\n';
return 0;
}
void prelucrare()
{
for(int i =1 ;i <= k; i ++)
rmq[i][0] = i;
int log = 0;
while( (1<<(log + 1)) <= k)
log++;
for(int j = 1 ;j <= log; j ++)
{
for(int i = 1 ;i<= k - (1<<j) + 1;i ++)
{
if(nivel[rmq[i][j - 1]] < nivel[rmq[i + (1<<(j-1)) ][j -1]])
rmq[i][j] = rmq[i][j - 1];
else
rmq[i][j] =rmq[i + (1<<(j-1)) ][j - 1];
}
}
}
int LCA(int x, int y)
{
return queryRMQ(poz[x],poz[y]);
}