Pagini recente » Cod sursa (job #1334387) | Cod sursa (job #851730) | Istoria paginii runda/pregg/clasament | Cod sursa (job #1813897) | Cod sursa (job #2499354)
#include <bits/stdc++.h>
#define DIM 200010
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n,m,i,j,k,e[DIM],f[DIM],niv[DIM],putere,x,y,l[DIM],d[25][DIM];
vector<int> L[DIM/2];
void euler(int nod,int nivel) { //reprezentarea euler a arborelui
e[++k]=nod, niv[k]=nivel, f[nod]=k;
for (int i=0;i<L[nod].size();i++) {
int vecin=L[nod][i];
euler(vecin,nivel+1);
e[++k]=nod, niv[k]=nivel;
}
}
int main() {
fin>>n>>m;
for (i=2;i<=n;i++) {
fin>>x;
L[x].push_back(i);
}
euler(1,1);
for (i=2;i<=k;i++)
l[i]=l[i/2]+1;
for (i=1;i<=k;i++)
d[0][i]=i;
for (i=1;i<=l[k];i++) { //cu rmq calculam nivelul minim din orice interval
for (j=1;j<=k;j++) {
d[i][j]=d[i-1][j];
if (j+(1<<(i-1))<=k)
if (niv[d[i][j]]>niv[d[i-1][j+(1<<(i-1))]])
d[i][j]=d[i-1][j+(1<<(i-1))];
}
}
while (m--) {
fin>>x>>y;
x=f[x], y=f[y]; //prima pozitie in care apar x si y in reprezentarea euler
if (x>y)
swap(x,y);
putere=l[y-x+1];
//LCA este nodul cu nivelul minim din intervalul [x,y]
if (niv[d[putere][x]]<niv[d[putere][y-(1<<putere)+1]])
fout<<e[d[putere][x]]<<"\n";
else
fout<<e[d[putere][y-(1<<putere)+1]]<<"\n";
}
return 0;
}