Cod sursa(job #1674336)

Utilizator mihai.constantinConstantin Mihai mihai.constantin Data 4 aprilie 2016 16:44:00
Problema Stramosi Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2 kb
#include <iostream>
#include <cstdio>
using namespace std;

const int N_max = 250002;
const int M_max = 300002;
const int Log = 20;

int lst[N_max];
int urm[N_max];
int vf[N_max];
int nr;

int tata[N_max];
int level[N_max];

bool viz[N_max];

int A[Log][N_max]; /* A[i][j] == AL 2 ^ i STRAMOS AL LUI j */

int Lg[N_max];

int N, Q;

void adauga(int x, int y)
{
    // ADAUGA IN LISTA LUI x PE y

    nr++;
    vf[nr] = y;
    urm[nr] = lst[x];
    lst[x] = nr;
}

void dfs(int x)
{
    int p, y;

    viz[x] = true;

    // PARCURG VECINII y AI LUI x

    p = lst[x];

    while(p != 0)
    {
        y = vf[p];

        if(!viz[y])
        {
            level[y] = 1 + level[x];
            dfs(y);
        }

        p = urm[p];
    }
}

void read()
{
    freopen("stramosi.in", "r", stdin);

    int i, j;

    scanf("%d %d", &N, &Q);

    for(i = 1; i <= N; i++)
    {
        scanf("%d", &tata[i]);

        adauga(tata[i], i);
    }

    for(i = 1; i <= N; i++)
        if(!tata[i]) dfs(i);

    /* CONSTRUIESC MATRICEA A */

    for(i = 1; i <= N; i++) A[0][i] = tata[i]; /* PRIMUL STRAMOS AL NODULUI i ESTE CHIAR TATAL ACESTUIA */

    for(i = 1; (1 << i) <= N; i++)
        for(j = 1; j <= N; j++)
        /* RECURENTA */
            if(A[i - 1][j]) A[i][j] = A[ i - 1 ][ A[i - 1][j] ];

    /* CONSTRUIESC VECTORUL Lg */
    Lg[1] = 0;
    for(i = 2; i <= N; i++) Lg[i] = 1 + Lg[i/2];
}

int query()
{
    int i, j, node, P, L, lg;

    for(i = 1; i <= Q; i++)
    {
        scanf("%d %d", &node, &P);

        L = level[node] - P;

        if(L < 0) return 0;

        /*
            for(lg = 0; (1 << lg) <= level[node]; lg++);
            lg--;
        */

        lg = Lg[node];

        for(j = lg; j >= 0; j--)
            if(A[j][node] && level[A[j][node]] >= L) node = A[j][node];

        /* ACUM NODUL node SE AFLA PE NIVELUL L. AFISEZ SOLUTIA */

        return node;
    }
}

int main()
{
    freopen("stramosi.out", "w", stdout);

    int i;

    read();

    for(i = 1; i <= Q; i++) printf("%d\n", query());

    return 0;
}