Pagini recente » Cod sursa (job #2319010) | Cod sursa (job #2315662) | Cod sursa (job #3185021) | Cod sursa (job #856030) | Cod sursa (job #2723000)
//lca cu arbore de intervale
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
const int maxn = 100005;
struct xy { int x, y; };
xy a[maxn];
int k;
vector <int> v[maxn];
int first[maxn];
class arbint {
private:
int v[17 * maxn], n, qa, qb;
int build(int nod, int st, int dr, xy a[]) {
if(st == dr) {
v[nod] = st;
return v[nod];
}
int mid = (st + dr) / 2;
int x1 = build(nod * 2, st, mid, a);
int x2 = build(nod * 2 + 1, mid + 1, dr, a);
if(a[x1].y < a[x2].y) {
v[nod] = x1;
} else {
v[nod] = x2;
}
return v[nod];
}
int query(int nod, int st, int dr) {
if(st >= qa && dr <= qb) {
return v[nod];
}
int mid = (st + dr) / 2;
int ans = 1 << 30, ians;
if(qa <= mid) {
int x1 = query(nod * 2, st, mid);
if(a[x1].y < ans) {
ans = a[x1].y;
ians = x1;
}
}
if(qb >= mid + 1) {
int x2 = query(nod * 2 + 1, mid + 1, dr);
if(a[x2].y < ans) {
ans = a[x2].y;
ians = x2;
}
}
return ians;
}
public:
void build(int sz, xy a[]) {
n = sz;
build(1, 1, n, a);
}
int query(int st, int dr) {
if(st > dr) { swap(st, dr); }
qa = st; qb = dr;
int qans = query(1, 1, n);
return a[qans].x;
}
};
arbint ai;
void dfs(int x, int niv) {
a[++k] = {x, niv};
if(first[x] == 0) {
first[x] = k;
}
for(auto u : v[x]) {
dfs(u, niv + 1);
a[++k] = {x, niv};
}
}
int main()
{
int n, t, i, x, y;
f >> n >> t;
for(i = 2; i <= n; i ++) {
f >> x;
v[x].push_back(i);
}
dfs(1, 0);
ai.build(k, a);
while(t --) {
f >> x >> y;
g << ai.query(first[x], first[y]) << '\n';
}
f.close(); g.close();
return 0;
}