Pagini recente » Cod sursa (job #2215678) | Istoria paginii runda/pre_oni_3_star | Cod sursa (job #782445) | Cod sursa (job #2226412) | Cod sursa (job #2351838)
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define MOD 1000000007
using namespace std;
typedef long long ll;
typedef pair< int , int > PII;
ll n, a[100100], x, y, m, k;
string s;
class RMQ {
private:
vector < int > logVec;
vector < vector < int > > rmqVec;
public:
RMQ(vector < int > _RMQ){
logVec.assign(_RMQ.size() + 1, 0);
for (int i = 2; i < logVec.size(); i++) {
logVec[i] = logVec[i / 2] + 1;
}
rmqVec.assign(logVec.back() + 1, vector < int >(_RMQ.size()));
rmqVec[0] = _RMQ;
for (int logX = 1; logX < rmqVec.size(); logX++) {
for (int i = 0; i + (1 << logX) <= _RMQ.size(); i++) {
rmqVec[logX][i] = min(rmqVec[logX - 1][i], rmqVec[logX - 1][i + (1 << (logX - 1))]);
}
}
}
int getMin(int l, int r) { // ! returns the answer for the interval [l, r) !
int logX = logVec[r - l];
return min(rmqVec[logX][l], rmqVec[logX][r - (1 << logX)]);
}
};
vector < int > bck;
vector < int > fst;
vector < int > euler;
vector < int > V[100100];
void eulerTour(int curr, int dad) {
int newIndex = bck.size();
bck.push_back(curr);
fst[curr] = euler.size();
euler.push_back(newIndex);
for (auto it : V[curr]) {
if (it == dad) continue;
eulerTour(it, curr);
euler.push_back(newIndex);
}
}
int main(){
ifstream cin("lca.in");
ofstream cout("lca.out");
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> n >> m;
for (int i = 1, x; i < n; i++) {
cin >> x;
V[x].push_back(i + 1);
}
fst.assign(n + 1, -1);
eulerTour(1, 1);
RMQ rmq(euler);
while (m--) {
int x, y;
cin >> x >> y;
int nodeX = fst[x], nodeY = fst[y];
if (nodeX > nodeY) swap(nodeX, nodeY);
int newIndex = rmq.getMin(nodeX, nodeY + 1);
int oldIndex = bck[newIndex];
cout << oldIndex << "\n";
}
return 0;
}