Pagini recente » Monitorul de evaluare | Profil dark_angel | Cod sursa (job #122259) | Cod sursa (job #31192) | Cod sursa (job #2010485)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream in ("lca.in");
ofstream out ("lca.out");
int const nmax = 100000;
vector<int> g[1 + nmax];
int n;
int v[1 + 2*nmax], nv;
int pos[1 + 2*nmax], depth[1 + nmax];
void dfs(int node){
for(int i = 0; i < g[node].size(); i++){
if(0 < i) {
v[++nv] = node;
pos[node] = nv;
}
depth[g[node][i]] = depth[node] + 1;
dfs(g[node][i]);
}
if(g[node].size() <= 1) {
v[++nv] = node;
pos[node] = nv;
}
}
int binarysearch(int from, int to, int dif){
//cout<<from<<" "<<to<<" "<<dif<<'\n';
if(from < to) {
int mid = (from + to) / 2;
if((1 << mid) < dif) {
return binarysearch(mid + 1, to, dif);
} else {
return binarysearch(from, mid, dif);
}
} else {
return from;
}
}
//rmq[i][p] imi tine minte pozitia j din v, astfel incat depth[v[j]] e minim pe intervalul [i, i + 2^p]
int rmq[20][1 + 2 * nmax];
int minrmq(int from, int to, int pow2) {
int i = rmq[pow2][from];
int j = rmq[pow2][to - (1 << pow2)];
if(depth[v[i]] < depth[v[j]]){
return i;
} else {
return j;
}
}
void computermq() {
for(int j = 1 ; j < nv ;j++){
if(depth[v[j]] < depth[v[j + 1]]) {
rmq[0][j] = j;
} else{
rmq[0][j] = j + 1;
}
}
for(int i = 1; i < 20; i++) {
int lim = nv - (1 << i);
for(int j = 1; j <= lim ;j++ ) {
rmq[i][j] = minrmq(j, j + (1 << i), i - 1);
}
}
}
int main() {
int q;
in >> n >> q;
int a, b;
for(int i = 2; i <= n; i++) {
in >> a;
g[a].push_back(i);
}
dfs(1);
computermq(); //ai rmq
for(int i = 0 ; i < q; i++){
in >> a >> b;
if(a == b) {
out << a << '\n';
} else {
int x = pos[a];
int y = pos[b];
if(y < x)
swap(x, y);
//cout<<x<<" "<<y<<" -> "<<endl;
int pow2 = binarysearch(0, 21, y - x);
if(y - x < (1<<pow2))
pow2--;
out<< v[minrmq(x , y , pow2)] << '\n';
}
}
return 0;
}