Pagini recente » Cod sursa (job #1201684) | Cod sursa (job #930962) | Cod sursa (job #2366204) | Cod sursa (job #1254897) | Cod sursa (job #2759462)
/*
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];
void DFS(int nod, int height){
for(int i = 0; i < v[nod].size(); i++){
int X = v[nod][i];
//ii calculez stramosii lui X, dupa care il dau mai departe
//pornesc cu j de la 1 pt ca tt[X][0] il stiu deja din citire
for(int j = 1; (1 << j) <= height; j++){ //un for foarte gandit
//practic iau doar tatii care exista
tt[X][j] = tt[ tt[X][j - 1] ][j - 1];
}
DFS(X, height + 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);
}
DFS(0, 0); //de fapt asta e un fel de buildTT[][]
//adica aici pregatesc pt query-urile ce urmeaza
for(int i = 1; i <= M; i++){
int Q, P;
fin >> Q >> P;
fout << query(Q, P) << "\n";
}
return 0;
}