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"; } }