Pagini recente » Cod sursa (job #2494492) | Cod sursa (job #3289850) | Cod sursa (job #653358) | Cod sursa (job #3179074) | Cod sursa (job #3207933)
#include <iostream>
#include <vector>
const int MAX = 100001;
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
int n, q;
vector<vector<int> > adj;
///lca
bool vizitat[MAX];
int euler[MAX];
int height[MAX];
int low[MAX];
///rmq
int rmq[18][MAX];
int bitSemnificativ[MAX];
void dfs(int node, int& index)
{
vizitat[node] = true;
euler[++index] = node;
for(auto vecin : adj[node])
{
if(!vizitat[vecin])
{
height[vecin] = height[node] + 1;
low[vecin] = index + 1;
dfs(vecin, index);
euler[++index] = node;
}
}
}
int lca(int x, int y)
{
int st = low[x];
int dr = low[y];
if(st > dr) swap(st, dr);
int e = bitSemnificativ[dr-st+1];
int len = 1<<e;
int sol = min(rmq[e][st], rmq[e][dr - len + 1]);
/*cout<<"NODURILE : x = "<<x<<" si y = "<<y<<'\n';
cout<<"APARITII MINIME : "<<st<<" "<<dr<<'\n';
cout<<"LOCATIE EULER "<<sol<<"\n\n";*/
return sol;
}
int main()
{
cin>>n>>q;
adj.resize(n+1);
for(int i = 2; i <= n;i++)
{
int x;
cin >> x;
adj[x].push_back(i);
}
int index = 0;
dfs(1, index);
/*cout<<"HEIGHTS :\n";
for(int i = 1;i<=n;i++) cout<<height[i]<<" ";
*/
///rmq
bitSemnificativ[1] = 0;
for(int i = 2;i<=index;i++)
{
bitSemnificativ[i] = bitSemnificativ[i>>1] + 1;
}
for(int i = 1; i<=index;i++) rmq[0][i] = euler[i];
for(int e = 1; (1<<e) <= index; e++)
{
for(int i = 1;i<=index;i++)
{
int j = i + (1<<(e-1));
rmq[e][i] = rmq[e-1][i];
if(j<=index && height[rmq[e-1][i]] > height[rmq[e-1][j]])
rmq[e][i] = rmq[e-1][j];
}
}
/*
cout<<'\n';
cout<<"RMQ :\n";
for(int e = 0; (1<<e)<= 17;e++)
{
for(int i = 1;i<=index;i++) cout<<rmq[e][i]<<" ";
cout<<'\n';
}
cout<<"\nEULER :\n";
for(int i = 1; i<=index;i++) cout<<euler[i]<<" ";
cout<<"\n\n";*/
while(q--)
{
int x, y;
cin>>x>>y;
cout << lca(x, y) <<"\n";
}
}