Cod sursa(job #1608591)

Utilizator laurageorgescuLaura Georgescu laurageorgescu Data 22 februarie 2016 10:48:33
Problema Cerere Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.62 kb
#include<cstdio>

using namespace std;

FILE *fin = fopen( "cerere.in", "r" ), *fout = fopen( "cerere.out", "w" );

const int nmax = 1e5;
const int lgmax = 16;
const int Size = 3 * 1e6;
int n;
int ans[ nmax + 1 ], c[ nmax + 1 ];
int d[ lgmax + 1 ][ nmax + 1 ];

int poz;
char buff[ Size ];

char next_poz() {
    ++ poz;
    if ( poz == Size ) {
        fread( buff, Size, 1, fin );
        poz = 0;
    }
    return buff[ poz ];
}
void get_nmb( int &x ) {
    x = 0;
    char c = next_poz();
    while ( c < '0' || c > '9' ) {
        c = next_poz();
    }
    while ( c >= '0' && c <= '9' ) {
        x = x * 10 + c - '0';
        c = next_poz();
    }
}
void calculeaza_stramosi() {
    for( int i = 1; (1 << i) <= n; ++ i ) {
        for( int j = 1; j <= n; ++ j ) {
            d[ i ][ j ] = d[ i - 1 ][ d[ i - 1 ][ j ] ];
        }
    }
}
int tata( int x, int k ) {
    int sol = x;
    for( int i = 0; (1 << i) <= k; ++ i ) {
        if ( k & (1 << i) ) {
            sol = d[ i ][ sol ];
        }
    }
    return sol;
}
int solve( int x ) {
    if ( ans[ x ] > 0 ) {
        return ans[ x ];
    }
    if ( c[ x ] == 0 ) {
        return 1;
    }
    return ( ans[ x ] = solve( tata( x, c[ x ] ) ) + 1 );
}
int main() {
    poz = Size - 1;

    get_nmb( n );
    for( int i = 1; i <= n; ++ i ) {
        get_nmb( c[ i ] );
    }
    for( int i = 1; i < n; ++ i ) {
        int x, y;
        get_nmb( x ); get_nmb( y );
        d[ 0 ][ y ] = x;
    }
    calculeaza_stramosi();

    for( int i = 1; i <= n; ++ i ) {
        fprintf( fout, "%d ", solve( i ) - 1 );
    }
    fprintf( fout, "\n" );
    fclose( fin );
    fclose( fout );
    return 0;
}