Pagini recente » Cod sursa (job #248112) | Cod sursa (job #150677) | Cod sursa (job #2382892) | Cod sursa (job #2858845) | Cod sursa (job #2283876)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
void Euler(int currentNode, vector<int> a[], int euler[], int ¤tSize) {
euler[currentSize] = currentNode;
currentSize ++;
for (int i = 0; i < a[currentNode].size(); ++i) {
int currentChild = a[currentNode][i];
Euler(currentChild, a, euler, currentSize);
euler[currentSize] = currentNode;
currentSize ++;
}
}
void createHeight(int currentNode, vector <int> a[], int height[], int currentHeight) {
height[currentNode] = currentHeight;
for (int i = 0; i < a[currentNode].size(); ++i) {
int currentChild = a[currentNode][i];
createHeight(currentChild, a, height, currentHeight + 1);
}
}
void createRMQ(int n, int **RMQ, int height[], int euler[], int eSize, int firstAppearPosition[], int **pRMQ) {
int put[30]; /// put[i] = 2 ^ i;
put[0] = 1;
int lgmax = 0;
for (int i = 1; 2 * put[i - 1] <= eSize; ++i) {
put[i] = 2 * put[i - 1];
lgmax ++;
}
for (int i = 0; i < eSize; ++i) {
RMQ[i][0] = height[euler[i]];
pRMQ[i][0] = euler[i];
}
for (int j = 1; j <= lgmax; ++j) {
for (int i = 0; i + put[j - 1] < eSize; ++i) {
RMQ[i][j] = RMQ[i][j - 1];
pRMQ[i][j] = pRMQ[i][j - 1];
if ( RMQ[i][j - 1] > RMQ[i + put[j - 1]][j - 1] ) {
RMQ[i][j] = RMQ[i + put[j - 1]][j - 1];
pRMQ[i][j] = pRMQ[i + put[j - 1]][j - 1];
}
}
}
}
int lca(int x, int y, int euler[], int **RMQ, int firstAppearPosition[], int **pRMQ) {
if (firstAppearPosition[x] > firstAppearPosition[y]) { swap(x, y); }
int p = 0;
while ( (1 << p) < ( firstAppearPosition[y] - firstAppearPosition[x] + 1) ) {
p ++;
}
p --;
int pminim = pRMQ[firstAppearPosition[x]][p];
if ( RMQ[firstAppearPosition[x]][p] > RMQ[firstAppearPosition[y] - (1 << p) ][p] ) {
pminim = pRMQ[firstAppearPosition[y] - (1 << p) ][p];
}
return pminim;
}
int main() {
ifstream f("lca.in");
ofstream g("lca.out");
int n, m;
f >> n >> m;
vector <int> a[n + 1];
for (int i = 0; i < n; ++i) {
a[i + 1].clear();
}
for (int i = 2; i <= n; ++i) {
int current_father;
f >> current_father;
a[current_father].push_back(i);
}
int euler[5 * n], height[n + 1];
int eSize = 0;
Euler(1, a, euler, eSize);
createHeight(1, a, height, 0);
int firstAppearPosition[n + 1];
for (int i = 0; i <= n; ++i) {
firstAppearPosition[i] = -1;
}
for (int i = 0; i < eSize; ++i) {
if ( firstAppearPosition[euler[i]] == -1 ) {
firstAppearPosition[euler[i]] = i;
}
}
int **RMQ = new int*[eSize + 1];
int **pRMQ = new int*[eSize + 1];
for (int i = 0; i <= eSize; ++i) {
RMQ[i] = new int[20];
pRMQ[i] = new int[20];
}
createRMQ(n + 1, RMQ, height, euler, eSize, firstAppearPosition, pRMQ);
while (m --) {
int x, y;
f >> x >> y;
g << lca(x, y, euler, RMQ, firstAppearPosition, pRMQ) << "\n";
}
return 0;
}