Pagini recente » Clasament preONI 2007, Runda 3, Clasa a 10-a | Cod sursa (job #168959) | Cod sursa (job #166129) | Cod sursa (job #3212312) | Cod sursa (job #531892)
Cod sursa(job #531892)
#include<cstdio>
#include<vector>
using namespace std;
#define MAXN 100001
int N, M, E;
vector<int> tree[MAXN];
int euler[2*MAXN];
int depth[2*MAXN];
int ap[MAXN];
void buildEuler(int node,int dep) {
euler[++E] = node; depth[E] = dep;
if (!ap[node]) ap[node] = E;
for( int i = 0; i < tree[node].size(); i++) {
buildEuler(tree[node][i], dep + 1);
euler[++E] = node; depth[E] = dep;
}
}
int arb[4*MAXN + 1];
int val, pos;
int left, right;
int min(int a, int b) {
return depth[ap[a]] < depth[ap[b]]? a: b;
}
void update(int nod, int st, int dr) {
if (st == dr) {
arb[nod] = euler[pos];
return;
}
int mij = (st + dr) / 2;
if (pos <= mij) update(nod * 2, st, mij);
else update(nod * 2 + 1, mij + 1, dr);
arb[nod] = min (arb[2*nod], arb[2*nod+1]);
}
int arb_min(int nod, int st, int dr) {
if (left <= st && dr <= right) return arb[nod];
int mij = (st + dr) / 2;
int maxleft, maxright;
maxleft = maxright = INT_MAX;
if (left <= mij) maxleft = arb_min(nod * 2, st, mij);
if (mij < right) maxright = arb_min(nod * 2 + 1, mij + 1, dr);
return min(maxleft, maxright);
}
int main() {
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
scanf("%d %d", &N, &M);
int father;
for (int i = 2; i <= N; i++) {
scanf("%d", &father);
tree[father].push_back(i);
}
E = 0;
buildEuler(1,0);
for (int i = 1; i <= E; i++) {
val = depth[i];
pos = i;
update(1,1,E);
}
int a,b;
for (int i = 0; i < M; i++) {
scanf("%d %d", &a, &b);
left = ap[a];
right = ap[b];
if (left > right) {
int aux = left; left = right; right = aux;
}
printf("%d\n", arb_min(1,1,E));
}
return 0;
}