Cod sursa(job #2759468)

Utilizator NeacsuMihaiNeacsu Mihai NeacsuMihai Data 17 iunie 2021 23:31:10
Problema Stramosi Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.94 kb
/*
    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;
}