Cod sursa(job #1675780)

Utilizator mihai.constantinConstantin Mihai mihai.constantin Data 5 aprilie 2016 16:06:09
Problema Cerere Scor 85
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.67 kb
#include <iostream>
#include <cstdio>
using namespace std;

FILE *in, *out;

const int N_max = 100002;
const int Size = 100000;
const int Log = 18;

int poz;
char buff[Size];

int v[N_max];

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

int NR;

int N;

char next_poz()
{
    ++poz;

    if(poz == Size)
    {
        fread(buff, 1, Size, in);
        poz = 0;
    }

    return buff[poz];
}

void get_number(int &nr)
{
    nr = 0;

    char c = next_poz();

    while(c < '0' || c > '9') c = next_poz();

    while(c >= '0' && c <= '9')
    {
        nr = nr * 10 + c - '0';

        c = next_poz();
    }
}

int Ancestor(int node, int p)
{
    int i = 0;

    NR++;

    while(p != 0)
    {
        if(p & 1) node = A[i][node];

        p >>= 1;

        i++;
    }

    if(!v[node]) return node;
    else
        Ancestor(node, v[node]);
}

int main()
{
    in = fopen("cerere.in", "r");
    out = fopen("cerere.out", "w");

    int i, j, x, y;

    poz = Size - 1;

    get_number(N);

    for(i = 1; i <= N; i++) get_number(v[i]);

    for(i = 1; i < N; i++)
    {
        get_number(x);
        get_number(y);

        A[0][y] = x; /* PRIMUL STRAMOS AL LUI y ESTE CHIAR TATAL ACESTUIA */
    }

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

    for(i = 1; i <= N; i++)
    {
        /* SUNT LA NODUL i SI VREAU SA AJUNG LA AL v[i] - LEA STRAMOS */

        NR = 0;
        if(!v[i]) fprintf(out, "%d ", NR);
        else
        {
            int rc = Ancestor(i, v[i]);

            fprintf(out, "%d ", NR);
        }
    }

    return 0;
}