Pagini recente » Cod sursa (job #109383) | Cod sursa (job #754817) | Cod sursa (job #2570903) | Cod sursa (job #1886035) | Cod sursa (job #2719850)
#include <fstream>
#include <vector>
#define DIM 100001
using namespace std;
vector<int> L[DIM];
int T[DIM], Niv[DIM], i, x, y, dif;
int D[DIM][18];
int n, m;
int S[DIM];
void dfs(int nod, int niv) {
Niv[nod] = niv;
S[niv] = nod;
for (int e=0; niv-(1<<e) >= 1; e++) {
D[nod][e] = S[niv - (1<<e)];
}
for (int i=0;i<L[nod].size();i++) {
int fiu = L[nod][i];
dfs(fiu, niv+1);
}
}
/// La fiecare nod voi calcula:
/// D[nod][e] = al 2^e - lea stramos al lui nod
int main () {
ifstream fin ("lca.in");
ofstream fout("lca.out");
fin>>n>>m;
for (i=2;i<=n;i++) {
fin>>T[i];
L[ T[i] ].push_back(i); /// liste de fii
}
dfs(1, 1);
/// T = vector de tati
/// Niv = vector cu nivelul fiecarui nod
int e;
while (m--) {
fin>>x>>y;
/**
Niv[x] = 7
Niv[y] = 13
Diferenta este 6 = (4+2)
y = D[y][1]; salt de 2
y = D[y][2]; salt de 4 din log(diferenta) pasi aduc cele 2 noduri la acelasi nivel
**/
if (Niv[x] > Niv[y]) {
dif = Niv[x] - Niv[y];
e = 0;
while (dif) {
if (dif % 2 == 1) {
x = D[x][e];
}
e++;
dif /= 2;
}
} else
if (Niv[x] < Niv[y]) {
dif = Niv[y] - Niv[x];
e = 0;
while (dif) {
if (dif % 2 == 1) {
y = D[y][e];
}
e++;
dif /= 2;
}
}
e = 0;
while ((1 << e) < n)
e++;
if (x == y) {
fout<<x<<"\n";
continue;
}
while (T[x] != T[y]) {
if ( D[x][e] != D[y][e] ) {
/// daca as sari in stramosul D[x][e] as fi inca prea jos
x = D[x][e];
y = x;
}
e--;
}
fout<<T[x]<<"\n";
/**
while (x!=y) {
x = T[x];
y = T[y];
}
**/
/// fout<<x<<"\n";
}
return 0;
}
/**
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
2 2 4 5 8 9 9 10 10 14 14 15 17 17 20 20 21 33
1
Caut pe 17
Initial: start = 1;
Exponent: putere = 5
ma uit la v[ start+(1<<putere)-1 ] gasesc prea mare indicele
start ramane pe loc, putere--,
ma uit la v[ start+(1<<putere)-1 ] = v[16] gasesc prea mare valoarea
start ramane pe loc, putere--,
ma uit la v[ start+(1<<putere)-1 ] = v[8] gasesc prea mica valoarea
start += 1<<putere, putere--, start = 9 si putere = 2, v[12] e mai mic
ma uit la v[ start+(1<<putere)-1 ] = v[8] gasesc prea mica valoarea
start += 1<<putere, putere--, start = 9 si putere = 2, v[12] e mai mic
start + (1<<32) - 1
**/