0w1

CFR Educational 15 E. Analysis of Pathes in Functional Graph ( Doubling )

Problem - E - Codeforces
Basic doubling technique, nothing quite special.

void solve(){
    int N; ll K; cin >> N >> K;
    vi F( N ), W( N );
    for( int i = 0; i < N; ++i )
        cin >> F[ i ];
    for( int i = 0; i < N; ++i )
        cin >> W[ i ];

    const int LOGN = 35;

    vector< vector< ll > > sumv( N, vector< ll >( LOGN ) );
    vvi minv( N, vi( LOGN ) ), succ( N, vi( LOGN ) );
    for( int i = 0; i < N; ++i )
        for( int j = 0; j < LOGN; ++j )
            succ[ i ][ j ] = -1;

    for( int i = 0; i < N; ++i )
        succ[ i ][ 0 ] = F[ i ],
        sumv[ i ][ 0 ] = W[ i ],
        minv[ i ][ 0 ] = W[ i ];

    for( int i = 0; i + 1 < LOGN; ++i )
        for( int j = 0; j < N; ++j ){
            int mid = succ[ j ][ i ];
            succ[ j ][ i + 1 ] = succ[ mid ][ i ];
            sumv[ j ][ i + 1 ] = sumv[ j ][ i ] + sumv[ mid ][ i ];
            minv[ j ][ i + 1 ] = min( minv[ j ][ i ], minv[ mid ][ i ] );
        }

    for( int i = 0; i < N; ++i ){
        ll sv = 0;
        int mv = 1e9;
        for( ll k = K, u = i, z = LOGN - 1; k > 0; --z )
            if( k >= 1LL << z )
                k -= 1LL << z,
                sv += sumv[ u ][ z ],
                mv = min( mv, minv[ u ][ z ] ),
                u = succ[ u ][ z ];
        cout << sv << " " << mv << "\n";
    }
}