Cod sursa(job #1674530)

Utilizator mihai.constantinConstantin Mihai mihai.constantin Data 4 aprilie 2016 18:32:32
Problema Stramosi Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.43 kb
#include <cstdio>
#include <queue>
using namespace std;

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

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

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];

queue <int> C;

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 BFS()
{
    int i, p, y, x;

    for(i = 1; i <= N; i++) level[i] = -1;

    // INSEREZ IN COADA NODURILE TATA

    for(i = 1; i <= N; i++)
        if(!A[0][i])
        {
            C.push(i);
            level[i] = 0;
        }

    while(!C.empty())
    {
        x = C.front();
        C.pop();

        // PARCURG VECINII y AI LUI x

        p = lst[x];

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

            if(level[y] == -1)
            {
                level[y] = 1 + level[x];

                C.push(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", &A[0][i]); /* PRIMUL STRAMOS AL NODULUI i ESTE CHIAR TATAL ACESTUIA */

        adauga(A[0][i], i);
    }

    /*
        for(i = 1; i <= N; i++)
            if(!A[0][i]) dfs(i);
    */

    BFS();

    /* CONSTRUIESC MATRICEA A */

    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 j, node, P, L, lg;

    scanf("%d %d", &node, &P);

    if(P == 0) return node;

    L = level[node] - P;

    if(L < 0) return 0;

    lg = Lg[level[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);

    read();

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

    return 0;
}