Pagini recente » Cod sursa (job #2468018) | Cod sursa (job #786402) | Cod sursa (job #1726675) | Cod sursa (job #2246863) | Cod sursa (job #1786715)
#include <iostream>
#include <fstream>
#include <vector>
#include <math.h>
using namespace std;
int const MAX_N = 100001;
int const MAX_M = 2000001;
int const ROOT = 1; //radacina
int N, M; //numarul de noduri, numarul de queries
vector<int> graph[MAX_N]; //reprezentarea grafului prin liste
vector<int> euler_rep; //reprezentarea euler cu noduri
vector<int> depth_rep; //reprezentare euler cu adancimi
int pos_node[MAX_N]; //pozitia fiecarui nod in reprezentarea euler
void DFS(int node, int depth) {
euler_rep.push_back(node);
depth_rep.push_back(depth);
pos_node[node] = depth_rep.size() - 1;
for (size_t i = 0; i < graph[node].size(); i++) {
DFS(graph[node][i], depth + 1);
depth_rep.push_back(depth);
euler_rep.push_back(node);
}
}
int rmq[3 * MAX_N][25];
void RMQ() {
int rows = depth_rep.size();
int cols = floor(log2(rows)) + 1;
//cout << rows << " " << cols << endl;
for (size_t i = 0; i < depth_rep.size(); i++) {
rmq[i][0] = i;
}
for (int j = 1; j < cols; j++) {
for (int i = 0; i + (1 << j) - 1 < rows; i++) {
int step = 1 << (j - 1);
int index1 = rmq[i][j - 1];
int index2 = rmq[i+step][j - 1];
if (depth_rep[index1] < depth_rep[index2])
rmq[i][j] = index1;
else
rmq[i][j] = index2;
}
}
}
int query_RMQ(int x, int y) {
int li = min(x, y);
int ls = max(x, y);
int len = ls - li + 1;
int step= floor(log2(len));
int rem = len - (1 << step);
if (depth_rep[rmq[li][step]] < depth_rep[rmq[li + rem][step]])
return euler_rep[rmq[li][step]];
return euler_rep[rmq[li + rem][step]];
}
int main() {
ifstream fin("lca.in");
ofstream fout("lca.out");
fin >> N >> M;
for (int i = 2; i <= N; i++) {
int father;
fin >> father;
graph[father].push_back(i);
}
DFS(ROOT, 0);
RMQ();
for (int i = 0; i < M; i++) {
int node1, node2;
fin >> node1 >> node2;
fout << query_RMQ(pos_node[node1], pos_node[node2]) << '\n';
}
fin.close();
fout.close();
return 0;
}