Pagini recente » Cod sursa (job #1351768) | Cod sursa (job #802056) | Cod sursa (job #939964) | Cod sursa (job #2568664) | Cod sursa (job #2155259)
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
#define NMAX 100005
#define LOGMAX 30
int n, m, LOGA[NMAX * 2 + 5], sparce[NMAX * 2 + 5][LOGMAX], poz[NMAX];
vector<int> a[NMAX], euler, h;
void buildEuler(int node, int dist){
euler.push_back(node);
h.push_back(dist);
if(!poz[node] && node != 1)
poz[node] = h.size() - 1;
int i, child;
for(i=0; i<(int) a[node].size(); i++){
child = a[node][i];
buildEuler(child, dist + 1);
h.push_back(dist);
euler.push_back(node);
}
}
int main(){
int x, y, i, j, index, l, k, low, high, rez, saiz;
FILE *fin, *fout;
fin = fopen("lca.in", "r");
fout = fopen("lca.out", "w");
fscanf(fin, "%d %d", &n, &m);
for(i=2; i<=n; i++){
fscanf(fin, "%d ", &x);
a[x].push_back(i);
}
poz[1] = 0;
buildEuler(1, 0);
///building sparce table
saiz = (int) h.size();
for(i=2; i<=saiz; i++)
LOGA[i] = LOGA[i/2] + 1;
for(i=0; i<saiz; i++)
sparce[i][0] = i;
for(j=1; (1 << j) <= saiz; j++){
for(i=0; i + (1 << j) - 1 <= saiz; i++){
if(h[ sparce[i][j-1] ] < h[ sparce[i + (1 << (j-1))][j-1] ])
sparce[i][j] = sparce[i][j-1];
else sparce[i][j] = sparce[i + (1 << (j-1))][j-1];
}
}
///lca
for(i=1; i<=m; i++){
fscanf(fin, "%d %d", &x, &y);
low = min(poz[x], poz[y]);
high = max(poz[x], poz[y]);
l = high - low + 1;
k = LOGA[l];
if(h[ sparce[low][k] ] < h[ sparce[low + l - (1 << k)][k] ])
rez = sparce[low][k];
else rez = sparce[low + l - (1 << k)][k];
fprintf(fout, "%d\n", euler[rez]);
}
fclose(fin);
fclose(fout);
return 0;
}