Cod sursa(job #228935)

Utilizator Adriana_SAdriana Sperlea Adriana_S Data 8 decembrie 2008 20:50:26
Problema Atac Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.42 kb
#include <stdio.h>
#include <vector>

using namespace std;

const int N_MAX = 32010;
const int INF = 2000000000;

vector <pair <int, int> > G[N_MAX];
int lg[N_MAX], level[N_MAX], parc[3 * N_MAX], vec, rmq[20][N_MAX], tata[N_MAX];
int fap[N_MAX], din[18][N_MAX], stram[18][N_MAX];

void euler(int nod)
{
	parc[++ parc[0]] = nod;
	fap[nod] = parc[0];
	for (vector <pair <int, int> >::iterator it = G[nod].begin(); it != G[nod].end(); ++ it) {
		vec = it -> second;
		if (!level[vec]) {
			tata[vec] = it -> first;
			stram[0][vec] = nod;
			level[vec] = level[nod] + 1;
			euler(vec);
			parc[++ parc[0]] = nod;
		}
	}
}

inline int MIN(int a, int b)
{
	return (a < b ? a : b);
}

inline int MAX(int a, int b)
{
	return (a > b ? a : b);
}

int find_stramos(int nod, int ram)
{
//	printf("nod = %d ram = %d\n", nod, ram);
	int step, str = nod, i;
	for (step = 1, i = 0; step < ram; step <<= 1, i ++);
	for (; step; step >>= 1, i --) {
		if (ram & step) {
			str = stram[i][str];
		}
	}
	return str;
}

int dist(int nod, int care)
{
//	printf("nod = %d care = %d\n", nod, care);
	int l = lg[care];
//	printf("l = %d\n", l);
	int mn = din[l][nod], ram = care - (1 << l);
//	printf("mn = %d, ram = %d\n", mn, ram);
	if (ram) {
		int str = find_stramos(nod, ram);
		mn = MIN(mn, din[l][str]);
	}

	return mn;
}

int main()
{
	freopen("atac.in", "r", stdin);
#ifndef _SCREEN_
	freopen("atac.out", "w", stdout);
#endif

	int N, M, P, U, V;
	scanf("%d %d %d\n", &N, &M, &P);
	for (int i = 2; i <= N; i ++) {
		scanf("%d %d\n", &U, &V);
		G[i].push_back(make_pair(V, U));
		G[U].push_back(make_pair(V, i));
	}

	level[1] = 1;
	euler(1);
	lg[1] = 0;
	for (int i = 2; i <= parc[0]; i ++) {
		lg[i] = lg[i >> 1] + 1;
	}

	for (int j = 1; j <= parc[0]; j ++) rmq[0][j] = j;
	for (int i = 1; i <= lg[parc[0]]; i ++) {
		for (int j = 1; j + (1 << i) - 1 <= parc[0]; j ++) {
			int st = rmq[i - 1][j], dr = rmq[i - 1][j + (1 << (i - 1))];
			if (level[parc[st]] < level[parc[dr]]) rmq[i][j] = st;
			else rmq[i][j] = dr;
		}
	}

	for (int i = 1; i <= lg[N]; i ++) {
		for (int j = 1; j <= N; j ++) {
			stram[i][j] = stram[i - 1][stram[i - 1][j]];
		}
	}

	for (int i = 1; i <= N; i ++) {
		din[0][i] = tata[i];
	}
	for (int j = 1; j <= N; j ++) {
		for (int i = 1; i <= lg[level[j] - 1]; i ++) {
//			printf("j = %d i = %d bla = %d stram = %d\n", j, i, din[i - 1][j], find_stramos(j, (1 << (i - 1))));
			din[i][j] = MIN(din[i - 1][stram[i - 1][j]], din[i - 1][j]);
//			printf("%d %d %d\n", i, j, din[i][j]);
		}
	}

	int X, Y, A, B, C, D;
	scanf("%d %d %d %d %d %d\n", &X, &Y, &A, &B, &C, &D);
	for (int i = 1; i <= M; i ++) {
//		printf("X = %d Y = %d\n", X, Y);
		int st = MIN(fap[X], fap[Y]), dr = MAX(fap[X], fap[Y]);
		int L = dr - st + 1;
 
		int lca;
		if (level[parc[rmq[lg[L]][st]]] < level[parc[rmq[lg[L]][st + L - (1 << lg[L])]]]) {
			lca = parc[rmq[lg[L]][st]];
		} else {
			lca = parc[rmq[lg[L]][st + L - (1 << lg[L])]];
		}
		int unde = level[lca];

//		printf("lca = %d unde = %d\n", lca, unde);
//		printf("%d %d\n", level[X] - unde, level[Y] - unde);

		int rez = 0;
		if (lca != X && lca != Y) {
			rez = MIN(dist(X, level[X] - unde), dist(Y, level[Y] - unde));
		}
		if (lca == X) {
			rez = dist(Y, level[Y] - unde);
		}
		if (lca == Y) {
			rez = dist(X, level[X] - unde);
		}
		if (X == Y) rez = 0;
		if (i >= M - P + 1) printf("%d\n", rez);
		int XX = (X * A + Y * B) % N + 1, YY = (Y * C + rez * D) % N + 1;
		X = XX, Y = YY;
//		printf("!!%d\n", din[1][3]);
//		printf("\n");
	}

	return 0;
}