Cod sursa(job #223037)

Utilizator webspiderDumitru Bogdan webspider Data 26 noiembrie 2008 18:58:47
Problema Atac Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.36 kb
#include <stdio.h>
#include <iostream>
#include <vector>

using namespace std;

const int maxN = 32021;
const int INF = 200000;

#define pb push_back
#define mp make_pair
#define ff first
#define ss second

int N, M, P;
int A, B, C, D;
int X, Y;

vector< pair<int, int> > muchie[ maxN ];
vector<int> coada;

int grandF[ maxN ][ 16 ];
int minM[ maxN ][ 16 ];
int level[ maxN ];

int AIB[ (1<<16) ];
int DEBUG;
int get_min( int nod, int st, int dr, int a, int b ) {
	if ( a<=st && dr <= b ) return AIB[ nod ];
	int mij = ( st + dr ) / 2;
	int rez1 = INF, rez2 = INF;
	if ( a <= mij ) rez1 = get_min( 2*nod, st, mij, a, b );
	if ( b > mij ) rez2 = get_min( 2*nod+1, mij+1, dr, a, b );
	return min( rez1, rez2 );
}	

int add_aib( int nod, int st, int dr, int a, int b, int val ) {
	if ( a<= st && dr <= b ) {
		AIB[ nod ] = val;
		return 0;
	}
	int mij = ( st + dr ) / 2;
	if ( a <= mij ) add_aib( 2*nod, st, mij, a, b, val );
	if ( b > mij ) add_aib( 2*nod+1, mij+1, dr, a, b, val );
	AIB[ nod ] = min( AIB[2*nod], AIB[2*nod+1]  ) ;
}



int DFS( int nodC, int lastB ) {
	level[ nodC ] = coada.size();
	if ( level[ nodC ] != 0 ) {	add_aib( 1, 1, (1<<15), level[nodC], level[ nodC ], lastB ); }
	for ( int i = 0; ( 1<<i ) <= level[ nodC ]; i++ ) {
		grandF[ nodC ][ i ] = coada[ level[nodC] - (1<<i) ];
		minM[ nodC ][ i ] = get_min( 1, 1, (1<<15),  level[nodC] - ( 1<<i ) + 1 , level[ nodC ] );
	}
	coada.pb( nodC );
	for ( int i = 0; i < muchie[ nodC ].size(); i++ ) {
		if ( !grandF[ muchie[nodC][i].ff ][ 0 ] && muchie[nodC][i].ff != 1 ) {
			DFS( muchie[nodC][i].ff, muchie[nodC][i].ss );		
		}
	}
	coada.pop_back();	
}

int changeXY( int &X, int &Y, int A, int B, int C, int D, int Z ) {
	int _X = ( X*A + Y*B ) % N+1;
	int _Y = ( Y*C + Z*D ) % N+1;
	X = _X;
	Y = _Y;
}	

int solve( int X, int Y ) {
	if ( X == Y ) return 0;
	int minUX = INF;
	int minUY = INF; 
	if ( level[X] > level[Y] ) {
			for ( int i = 15; i >= 0; i-- ) 
				if ( level[ grandF[ X ][ i ]  ] >= level[Y] && grandF[ X ][ i ] ) {
					minUX = min( minUX, minM[ X ][ i ] );
					X = grandF[ X ][ i ];
				}
		}
	
	if ( level[Y] > level[X]) {
			for ( int i = 15; i >= 0; i-- ) 
				if ( level[ grandF[ Y ][ i ]  ] >= level[X] && grandF[ Y ][ i ] ) {
					minUY = min( minUY, minM[ Y ][ i ] );
					Y = grandF[ Y ][ i ];
				}
		}
	if ( level[X] != level[Y] ) printf("beleeaaa\n");	
	if ( X == Y ) return min( minUX, minUY );
	for ( int i = 15; i >= 0; i-- )
		if ( grandF[ Y ][ i ] != grandF[ X ][ i ] ) {
			minUX = min( minUX, minM[ X ][ i ] );
			minUY = min( minUY, minM[ Y ][ i ] );
			X = grandF[ X ][ i ];
			Y = grandF[ Y ][ i ];
		}
	if ( grandF[Y][0] != grandF[X][0] ) printf(" bealeaaaa2\n");
	minUX = min( minUX, minM[X][0] );
	minUY = min( minUY, minM[Y][0] );
	return min( minUX, minUY );
}

int main()
{
	int U, V;
#ifndef PC_RUN
	freopen("atac.in","r",stdin);
	freopen("atac.out","w",stdout);
	DEBUG = 0;
#else
	freopen("data.in","r",stdin);
	freopen("data.out","w",stdout);
	DEBUG = 1;
#endif

	scanf("%d %d %d\n", &N, &M, &P );
	for ( int i = 2; i <= N; i++ ) {
		scanf("%d %d\n", &U, &V );
		muchie[ i ].pb( mp( U, V ) );
		muchie[ U ].pb( mp( i, V ) );
	}
	scanf("%d %d %d %d %d %d\n", &X, &Y, &A, &B, &C, &D );
	
	for ( int i = 1; i<(1<<16); i++ )
			AIB[i] = INF;

	DFS( 1, INF );
	
	
	for ( int K = 1; K <= M; K++ ) {
		int Sol = solve( X, Y );
	   	if ( K > ( M-P ) ) 	printf("%d\n", Sol );
		changeXY( X, Y, A, B, C, D, Sol );
	}
	
	return 0;
}