Cod sursa(job #1455020)

Utilizator theprdvtheprdv theprdv Data 27 iunie 2015 12:49:47
Problema Atac Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.27 kb
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#define MAXN 32001
#define min(x, y) ((x) < (y) ? (x) : (y))
#define max(x, y) ((x) > (y) ? (x) : (y))

using namespace std;

struct node{
	int fath, c;
} DST[18][MAXN];

int R[18][2 * MAXN], Log[2 * MAXN], Lev[MAXN], Fs[MAXN];
int N, M, P, A, B, C, D, X, Y, Z, no, max_h;
vector <int> G[MAXN];

inline int min_lev(int x, int y) { return Lev[x] < Lev[y] ? x : y; }

void DFS(int n = 1, int lv = 1){
	Fs[n] = ++no;
	Lev[n] = lv;
	R[0][no] = n;
	max_h = max(max_h, lv);

	for (int i = 0; i < (int)G[n].size(); ++i)
		DFS(G[n][i], lv + 1),
		R[0][++no] = n;
}

void RMQ(){
	for (int i = 2; i <= no; ++i) Log[i] = Log[i >> 1] + 1;

	for (int i = 1; (1 << i) <= no; ++i)
		for (int j = 1; j <= no - (1 << i) + 1; ++j)
			R[i][j] = min_lev(R[i - 1][j], R[i - 1][j + (1 << (i - 1))]);
}

inline int LCA(){
	int x = Fs[X], y = Fs[Y], diff, row;
	if (y < x) x ^= y ^= x ^= y;
	diff = y - x + 1;
	row = Log[diff];

	return min_lev(R[row][x], R[row][x + diff - (1 << row)]);
}

int find_dist(int y, int x){
	int q = Lev[y] - Lev[x], minn = 1 << 30;

	while (q)
		minn = min(minn, DST[Log[q]][y].c),
		y = DST[Log[q]][y].fath, q -= (1 << Log[q]);
	return minn;
}

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

	scanf("%d %d %d", &N, &M, &P);
	for (int i = 2, v, x; i <= N; ++i)
		scanf("%d %d", &x, &v),
		G[x].push_back(i),
		DST[0][i].fath = x, DST[0][i].c = v;
	DFS();
	RMQ();

	// compute min value between x and 2^i x's father
	for (int i = 1; (1 << i) < max_h; ++i)
		for (int j = 1; j <= N; ++j){
			if (Lev[j] <= (1 << i)) continue;
			DST[i][j].fath = DST[i - 1][DST[i - 1][j].fath].fath;
			DST[i][j].c = min(DST[i - 1][j].c, DST[i - 1][DST[i - 1][j].fath].c);
		}

	scanf("%d %d %d %d %d %d", &X, &Y, &A, &B, &C, &D);
	for (int i = 1, node, a, b, minn; i <= M; ++i){
		node = LCA();
		a = X != node ? find_dist(X, node) : 1 << 30;
		b = Y != node ? find_dist(Y, node) : 1 << 30;
		minn = min(a, b);
		if (minn == 1 << 30) minn = 0;
		if (i >= M - P + 1) printf("%d   (%d, %d)\n", minn, X, Y);

		// compute next X, Y
		Z = minn;
		X = (X * A + Y * B) % N + 1;
		Y = (Y * C + Z * D) % N + 1;
	}

	return 0;
}