Pagini recente » Cod sursa (job #2904197) | Cod sursa (job #2153802) | Cod sursa (job #1443540) | Cod sursa (job #1932387) | Cod sursa (job #2216693)
#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
#define MAX_N 100001
#define MAX_SIZE 200001
#define MAX_RMQ 400001
#define MAX_LOG 18
ifstream fIn("lca.in");
ofstream fOut("lca.out");
int euler[MAX_SIZE], level[MAX_SIZE], pos[MAX_N], rmq[MAX_RMQ][MAX_LOG], lg[MAX_SIZE];
int numNodes, numQueries, p;
vector<vector<int>> adjList(MAX_N);
void generateVectors(int currNode, int currLevel) {
euler[p] = currNode;
level[p] = currLevel;
pos[currNode] = p++;
for (auto nextNode : adjList[currNode]) {
generateVectors(nextNode, currLevel+1);
euler[p] = currNode;
level[p++] = currLevel;
}
}
void buildRmqAndLog() {
for (register int i = 2; i <= p; ++i) {
lg[i] = lg[i >> 1] + 1;
}
for (register int i = 0; i < p; ++i) {
rmq[i][0] = i;
}
auto logP = (int)log2((double)p);
for (register int j = 1; j <= logP; ++j) {
int lim = p - (1 << j);
for (register int i = 0; i < lim; ++i) {
int k = (1 << (j - 1));
rmq[i][j] = level[rmq[i][j - 1]] < level[rmq[i + k][j - 1]] ?
rmq[i][j - 1] : rmq[i + k][j - 1];
}
}
}
int main() {
int nodeX, nodeY;
fIn >> numNodes >> numQueries;
for (register int i = 2; i <= numNodes; ++i) {
fIn >> nodeX;
adjList[nodeX].push_back(i);
}
generateVectors(1, 0);
buildRmqAndLog();
for (register int i = 0; i < numQueries; ++i) {
fIn >> nodeX >> nodeY;
int posX = pos[nodeX];
int posY = pos[nodeY];
if (posX > posY) {
swap(posX, posY);
}
int len = posY - posX + 1;
int k = lg[len];
int diff = len - (1 << k);
int sol = level[rmq[posX][k]] < level[rmq[posX + diff][k]] ?
rmq[posX][k] : rmq[posX + diff][k];
fOut << euler[sol] << '\n';
}
fIn.close();
fOut.close();
return 0;
}