Cod sursa(job #3235415)

Utilizator le_fisheAndrei Opran le_fishe Data 17 iunie 2024 19:47:40
Problema Stramosi Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.49 kb
#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
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;
}