Cod sursa(job #770073)

Utilizator vendettaSalajan Razvan vendetta Data 21 iulie 2012 21:29:13
Problema Stramosi Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.86 kb
#include <iostream>
#include <fstream>

using namespace std;

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

#define nmax 250001
#define log_n 19

int stramos[log_n][nmax]; // tin pentru fiecare nod al 2^i-lea stramos; => adancimea maxima prima valoarea a lui i a.i. 2^i >= n => i = 18
int t[nmax];
int n, m;
void citeste(){

    f >> n >> m;
    for(int i=1; i<=n; i++){
        int x;
        f >> x;
        t[i] = x;
    }

}

int caut(int x){

    int poz = -1;
    while(x){
        ++poz;
        x = x / 2;
    }

    return poz;

}

void rezolva(){

    //fac matricea; a[2^i][nod] = X; => a[2^(i+1)][nod] = a[2^i][X];

    for(int i=1; i<=n; i++) stramos[0][i] = t[i];

    for(int i=1; i<log_n; i++){
        for(int j=1; j<=n; j++){
            int X = stramos[i-1][j];
            stramos[i][j] = stramos[i-1][X];
        }
    }

    // al p-lea stramos al lui X il voi afla : fie i a.i. 2^i <= p => acum voi afla al p-(2^i) stramos al lui nod;(nod fiind stramos[2^i][X];
    //practic pentru fiecare bit de 1 din reprezentarea binara a lui p  voi tot lua stramosi
    for(int i=1; i<=m; i++){
        int p, x;
        f >> x >> p;
        /*
        while( p ){
            //caut cel mai mare i a. i. 2^i <= p;
            int poz = caut(p);
            //cout << poz << '\n';
            //iau al 2^i-lea stramos al nodului x
            x = stramos[poz][x];
            //i-au acum voi cauta al (p-(2^i))-lea stramos al noului nod x(care e al 2^ilea stramos al lui x)
            p = p - (1<<poz);
        }
        g<< x<< "\n";
        */
        for(int j=0; (1<<j) <= p; j++){
            if  ((p & (1<<j) ) != 0)
                x = stramos[j][x];
        }
        g << x << "\n";
    }

}

int main(){

    citeste();
    rezolva();

    f.close();
    g.close();

    return 0;

}