Pagini recente » Borderou de evaluare (job #1762649) | Cod sursa (job #1984199) | Cod sursa (job #3261136) | Cod sursa (job #546298) | Cod sursa (job #3144209)
#include <fstream>
#include <vector>
#include <math.h>
#define pb push_back
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
int n, q, parent[100005], first[100005], v[210005], depth[210005], rmq[210005][20];
vector<int> a[100005];
void DFS(int nod, int adanc) {
v[++v[0]] = nod;
depth[v[0]] = adanc;
for(int i=0; i<a[nod].size(); i++) {
DFS(a[nod][i], adanc + 1);
v[++v[0]] = nod;
depth[v[0]] = adanc;
}
}
int pwr(int a) {
int pw = 1, exp = 0;
while(pw <= a) {
pw *= 2;
exp++;
}
return exp-1;
}
int get_min(int x, int y) {
int lg = pwr(y-x+1);
if(depth[rmq[x][lg]] < depth[rmq[y-(1<<lg)+1][lg]])
return v[rmq[x][lg]];
else return v[rmq[y-(1<<lg)+1][lg]];
}
int lca(int x, int y) {
int frstx = first[x];
int frsty = first[y];
return get_min(min(frstx, frsty), max(frstx, frsty));
}
int main()
{
in >> n >> q;
for(int i=2; i<=n; i++) {
int x;
in >> x;
parent[i] = x;
a[x].pb(i);
}
DFS(1, 1);
/*for(int i=1; i<=v[0]; i++)
out << depth[i] << ' ';
out << '\n';
for(int i=1; i<=v[0]; i++)
out << v[i] << ' ';
out << '\n';*/
for(int i=1; i<=v[0]; i++)
if(!first[v[i]])
first[v[i]] = i;
for(int j=0; (1<<j)<=v[0]; j++)
for(int i=1; i+(1<<j)-1<=v[0]; i++) {
if(!j)
rmq[i][j] = i;
else {
if(depth[rmq[i][j-1]] < depth[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];
}
}
while(q--) {
int x, y;
in >> x >> y;
out << lca(x, y) << '\n';
}
return 0;
}