Pagini recente » Cod sursa (job #3172656) | Cod sursa (job #222110) | Cod sursa (job #3157646) | Cod sursa (job #2468896) | Cod sursa (job #1098754)
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int NMAX = 100009;
int N; int T[NMAX]; vector<int> G[NMAX];int M; int level[NMAX * 2]; int euler[NMAX * 2]; int first[NMAX];
int A[1 << 19]; int min_ind;
void read() {
fin >> N >> M;
for(int i = 2; i <= N; ++i) {
int nod; fin >> nod;
T[i] = nod;
G[nod].push_back(i);
}
}
void dfs(int nod, int le) {
euler[++euler[0]] = nod;
level[euler[0]] = le;
first[nod] = euler[0];
for(unsigned i = 0; i < G[nod].size(); ++i) {
dfs(G[nod][i], le + 1);
euler[++euler[0]] = nod;
level[euler[0]] = le;
}
}
void update(int nod, int st, int dr, const int &pos) {
if(st == dr) {
A[nod] = pos;
return ;
}
int mid = (st + dr) / 2;
if(pos <= mid) update(nod * 2, st, mid, pos);
else update(nod * 2 + 1, mid + 1, dr, pos);
A[nod] = A[nod * 2];
if(level[A[nod * 2 + 1]] < level[A[nod]])
A[nod] = A[nod * 2 + 1];
}
void query(int nod, int st, int dr, const int &pos_st, const int& pos_dr) {
if(pos_st <= st && dr <= pos_dr) {
if(!min_ind || level[A[nod]] < level[min_ind]){
min_ind = A[nod];
}
return ;
}
int mid = (st + dr) / 2;
if(pos_st <= mid) query(nod * 2, st , mid, pos_st, pos_dr);
if(mid < pos_dr) query(nod * 2 + 1, mid + 1, dr, pos_st, pos_dr);
}
int main() {
read();
dfs(1, 0);
for(int i = 1; i <= euler[0]; ++i) {
update(1, 1, euler[0], i);
}
level[0] = (1<<30);
while(M--) {
int X; int Y; fin >> X >> Y;
min_ind = 0;
query(1, 1, euler[0], min(first[X], first[Y]), max(first[Y], first[X]));
fout << euler[min_ind] << '\n';
}
return 0;
}