Cod sursa(job #2179065)

Utilizator Dddarius95Darius-Florentin Neatu Dddarius95 Data 19 martie 2018 22:09:38
Problema Stramosi Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.34 kb
// stramosi - O(n log n + m * log(n))
#include <fstream>
#include <cmath>
#define LOGMAX 20
#define NMAX 250009

using namespace std;
ifstream f("stramosi.in");
ofstream g("stramosi.out");

int n, m, kmax;
int s[LOGMAX][NMAX];
// s[k][i] = al 2^k-lea stramos a lui i
// caz de bazaL s[0][i] = p[i]
//              s[k][i] = s[k-1][ s[k-1][i] ]

int build_ancestor() { // O(n log(n))
    for (int i = 1; i <= n; ++i) {
        f >> s[0][i]; // s[0][i] = p[i]
    }

    int kmax = log2(n);
    for (int k = 1; k <= kmax; ++k) {  // incercam lungimile in ordine crescatoare
        for (int i = 1; i <= n; ++i) {     // pt nodul i calculaam al 2^k-lea stramos al lui
            s[ k ][ i ] = s[ k - 1 ][ s[ k - 1 ][ i ] ];
        }
    }
}

//p = 21 = 1 + 4 + 16
//10101 - k = 0 - sare 2^0
//01010 - k = 1 -
//00101 - k = 2 - sare 2^2
//00010 - k = 3
//00001 - k = 4 - sare cu 2^4
//00000
int get_ancestor(int x, int p) { // O(log (n))
    int kmax = log2(n);

    for (int k = 0;  k <= kmax; ++k) {
        if (p & 1) {
            x = s[ k ][ x ];
        }

        p >>= 1; // ancestor /= 2
    }

    return x;
}

int main() {
    f >> n >> m;
    build_ancestor();

    for (int i = 1; i <= m; ++i) {
        int x, p;
        f >> x >> p;
        g << get_ancestor(x, p) << "\n";
    }

    return 0;
}