Pagini recente » Cod sursa (job #1000570) | Cod sursa (job #2660762) | Cod sursa (job #290453) | Cod sursa (job #2479670) | Cod sursa (job #2759468)
/*
Am facut alt build() in loc sa folosesc DFS
ca sa evit apelurile recursive
*/
/*
Observ ca numarul P poate fi descompus in baza 2
si exact asta fac
pt fiecare persoana tin minte stramosii pe puteri ale lui 2
si cand vreau sa fac al P-lea stramos, parcurg in descompunerea lui 2
si gasesc in timp logaritmic
timp: O(log N) pe query
memorie: O(N log N)
*/
/*
Problema imi da foarte comod '0' daca nu are stramos
adica o sa tin 0 radacina
*/
#include <iostream>
#include <fstream>
#include <vector>
#define NMAX 250000 //doua sute cincizeci de mii
#define LOGMAX 17
using namespace std;
ifstream fin ("stramosi.in");
ofstream fout ("stramosi.out");
vector<int> v[NMAX + 1];
int tt[NMAX + 1][LOGMAX + 1];
inline int logS(int x){
/*
Aceasta functie primeste ca parametru un element care este sigur de forma 2^K
deci are un singur bit egal cu 1
pe care il caut printr-o parcurgere
si returnez pozitia pe care l-am gasit
facand astfel un log in baza 2
*/
for(int j = 0; (1 << j) <= x; j++){
if(x & (1 << j) ){
return j;
}
}
}
inline int query(int Q, int P){
int nod = Q;
for(int i = P; i >= 1; i -= i & (-i)){
//o analogie cu AIB
nod = tt[nod][ logS( i & (-i) ) ];
}
return nod;
}
int main()
{
int N, M;
fin >> N >> M;
for(int i = 1; i <= N; i++){
fin >> tt[i][0];
v[ tt[i][0] ].push_back(i);
}
for(int pas = 1; pas <= LOGMAX; pas++){ //daca parcurg mai intai pasii, stiu sigur ca nu o sa apelez mai jos ceva ce nu a fost inca calculat
for(int i = 1; i <= N; i++){
tt[i][pas] = tt[ tt[i][pas - 1] ][pas - 1];
}
}
for(int i = 1; i <= M; i++){
int Q, P;
fin >> Q >> P;
fout << query(Q, P) << "\n";
}
return 0;
}