Pagini recente » Cod sursa (job #980754) | Cod sursa (job #1564314) | Cod sursa (job #2708267) | Cod sursa (job #1331813) | Cod sursa (job #2408408)
#include <cstdio>
#include <cctype>
#include <vector>
using namespace std;
const int SIZE = 1 << 17;
int pointer = SIZE;
char buffer[SIZE];
char Advance() {
if(pointer == SIZE) {
fread(buffer, 1, SIZE, stdin);
pointer = 0;
}
return buffer[pointer++];
}
int Read() {
int answer = 0;
char ch = Advance();
while(!isdigit(ch)) {
ch = Advance();
}
while(isdigit(ch)) {
answer = answer * 10 + ch - '0';
ch = Advance();
}
return answer;
}
const int N = 100000 + 7;
const int LG = 19;
int n, t;
vector <int> g[N];
int dep[N];
int euler[3 * N], top;
int first[N], last[N];
struct kek {
int fi;
int se;
};
kek rmq[3 * N][LG];
int mylog[3 * N];
void __read() {
n = Read();
t = Read();
for(int i = 2; i <= n; i++) {
int dad = Read();
g[dad].push_back(i);
}
}
void build(int nod) {
euler[++top] = nod;
first[nod] = last[nod] = top;
for(auto &nou : g[nod]) {
dep[nou] = 1 + dep[nod];
build(nou);
euler[++top] = nod;
last[nod] = top;
}
}
kek Min(kek a, kek b) {
if(a.fi < b.fi) {
return a;
} else {
return b;
}
}
void buildRMQ() {
for(int i = 2; i <= top; i++) {
mylog[i] = 1 + mylog[i / 2];
}
for(int i = 1; i <= top; i++) {
rmq[i][0] = {dep[euler[i]], i};
}
for(int k = 1; (1 << k) <= top; k++) {
for(int i = 1; i + (1 << k) - 1 <= top; i++) {
rmq[i][k] = Min(rmq[i][k - 1], rmq[i + (1 << (k - 1))][k - 1]);
}
}
}
int lca(int a, int b) {
int st = last[a];
int dr = first[b];
if(st > dr) {
swap(st, dr);
}
int k = mylog[dr - st + 1];
kek sol = Min(rmq[st][k], rmq[dr - (1 << k) + 1][k]);
return euler[sol.se];
}
int main() {
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
__read();
build(1);
buildRMQ();
while(t--) {
int a = Read(), b = Read();
printf("%d\n", lca(a, b));
}
return 0;
}