Pagini recente » Cod sursa (job #2636511) | Cod sursa (job #2650230) | Borderou de evaluare (job #1447462) | Borderou de evaluare (job #2331215) | Cod sursa (job #3235413)
#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
ifstream fin("stramosi.in");
ofstream fout("stramosi.out");
const int MAXN = 250000;
const int LOG = 18; // 2^18 este mai mare decât 250000, deci este suficient pentru a acoperi toate salturile posibile
vector<int> ancestor[MAXN + 1][LOG + 1]; // ancestor[i][j] va stoca al 2^j-lea strămoș al membrului i
// Funcție pentru preprocesarea strămoșilor folosind Binary Lifting
void preprocess(int N) {
for (int j = 1; j <= LOG; ++j) {
for (int i = 1; i <= N; ++i) {
if (ancestor[i][j - 1] != 0) { // Dacă există un strămoș la pasul anterior
ancestor[i][j] = ancestor[ancestor[i][j - 1]][j - 1];
}
}
}
}
// Funcție pentru a găsi al P-lea strămoș al membrului Q
int findAncestor(int Q, int P) {
for (int i = LOG; i >= 0; --i) {
if (P >= (1 << i)) {
Q = ancestor[Q][i];
P -= (1 << i);
if (Q == 0) break; // Dacă am ajuns la un membru fără strămoș
}
}
return Q;
}
int main() {
int N, M;
fin >> N >> M;
for (int i = 1; i <= N; ++i) {
fin >> ancestor[i][0]; // Strămoșul direct al fiecărui membru
}
preprocess(N); // Preprocesăm strămoșii
for (int i = 0; i < M; ++i) {
int Q, P;
fin >> Q >> P;
fout << findAncestor(Q, P) << '\n'; // Găsim și afișăm al P-lea strămoș al membrului Q
}
fin.close();
fout.close();
return 0;
}