Pagini recente » Cod sursa (job #583116) | Cod sursa (job #1324081) | Cod sursa (job #2636952) | Cod sursa (job #803138) | Cod sursa (job #377109)
Cod sursa(job #377109)
#include <iostream>
#include <fstream>
#include <vector>
#include <math.h>
using namespace std;
vector<int> G[100001];
int H[100001], poz[100001], k, rmq[20][100001], L[100001];
void DFS(int nod, int lev) {
//parcurgere Euler
//nodurile sunt stocate in H[ ] si prima pozitia pe care apar ele in poz[ ]
H[++k]=nod;
L[k]=lev;
poz[nod]=k;
for(vector<int>::iterator it=G[nod].begin(); it!=G[nod].end(); it++) {
DFS(*it, lev+1);
H[++k]=nod;
L[k]=lev;
}
}
int min(int a, int b){
if(a<b) { return a; }
return b;
}
int main() {
fstream f1, f2;
int n, m, i, j, p, q, x, y, aux;
int lg[200002], sol;
f1.open("lca.in", ios::in);
f1>>n>>m;
for(i=2; i<=n; i++) {
f1>>p;
G[p].push_back(i);
}
DFS(1, 0);
lg[1]=0;
for(i=2; i<=k; i++) {
lg[i]=lg[i >> 1] + 1;
}
for(i=1; i<=k; i++) {
rmq[0][i]=i;
}
for(i=1; (1<<i)<k; i++) {
for(j=1; j<=k-(1 << i)+1; j++) {
int l = 1 << (i - 1);
rmq[i][j]=rmq[i-1][j];
if(L[rmq[i-1][j+l]]<L[rmq[i][j]]) {
rmq[i][j] = rmq[i-1][j+l];
}
}
}
f2.open("lca.out", ios::out);
for(i=1; i<=m; i++) {
f1>>p>>q;
//returneaza minimul secventei dintre poz[p], poz[q];
p=poz[p]; q=poz[q];
if(p>q) { swap(p, q); }
//(int)(floor(log2((double)(n))));
x=lg[q-p+1];
aux=q-p+1-(1 << x);
//rmq[x][p], rmq[x][p+aux]
sol=rmq[x][p];
if(L[sol]>L[rmq[x][p+aux]]) {
sol=rmq[x][p+aux];
}
f2<<H[sol]<<endl;
}
f1.close(); f2.close();
return 0;
}