Pagini recente » Cod sursa (job #594937) | Cod sursa (job #920265) | Cod sursa (job #1094827) | Cod sursa (job #383166) | Cod sursa (job #709509)
Cod sursa(job #709509)
#include <fstream>
#include <vector>
#define nmax 100005
using namespace std;
int n, m;
vector<int> gf[nmax];
int D[nmax*2]; // D[i] = distanta de la i la radacina
int Euler[nmax*2];//nodurile in parcurgerea euler
int Ord[nmax];//Ordinea nodurile cum apar in parcurgere
int k;
int NOD, rez;
int arb[nmax*4];
ifstream f("lca.in");
ofstream g("lca.out");
void citeste(){
f >> n >> m;
for(int i=2; i<=n; i++){
int x;
f >> x;
gf[x].push_back(i);
}
}
void udpate(int nod, int st, int dr, int poz, int val){
if (st == dr){
arb[nod] = st;
return;
}
int mij = (st + dr) / 2;
if (poz <= mij) udpate(nod*2, st, mij, poz, val);
else udpate(nod*2+1, mij+1, dr, poz, val);
arb[nod] = arb[nod*2];
if (D[arb[nod]] > D[arb[nod*2+1]]) arb[nod] = arb[nod*2+1];
}
void query(int nod, int st, int dr, int a, int b){
if (a <= st && dr <= b){
if (D[arb[nod]] < rez){
NOD = Euler[arb[nod]];
rez = D[arb[nod]];
}
return;
}
int mij = (st + dr) / 2;
if (a <= mij) query(nod*2, st, mij, a, b);
if (b > mij) query(nod*2+1, mij+1, dr, a, b);
}
void dfs(int nod, int niv){
++k;
D[k] = niv;
Euler[k] = nod;
Ord[nod] = k;
for(int i=0; i<gf[nod].size(); i++){
dfs(gf[nod][i], niv+1);
++k;
D[k] = niv;
Euler[k]=nod;
}
}
void rezolva(){
for(int i=1; i<=k; i++){
udpate(1,1,k,i,i);
}
//for(int i=1; i<=k*2; i++) g << arb[i]<< " ";
for(int i=1; i<=m; i++){
int x, y;
f >> x >> y;
x = Ord[x];
y = Ord[y];
if ( x > y ) {
int aux = x;
x = y;
y = aux;
}
rez = (1<<29);
query(1, 1, k, x, y);
g << NOD << "\n";
}
}
int main(){
citeste();
dfs(1,1);
//for(int i=1; i<=k; i++) g << D[i] << "\n";
rezolva();
f.close();
g.close();
return 0;
}