Cod sursa(job #644876)

Utilizator darrenRares Buhai darren Data 7 decembrie 2011 18:50:23
Problema Atac Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.54 kb
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <vector>

using namespace std;

const int SIZE = 32002;
const int INF = 0x3f3f3f3f;
typedef vector<pair<int, int> > VP;

inline int iabs(int x)
{
	return (x < 0 ? -x : x);
}

int Log[2 * SIZE];
int N, M, P;
int X, Y, Z, A, B, C, D;
int niv[2 * SIZE], in[SIZE], out[SIZE], indnow;
int minv[SIZE][15], nod[SIZE][15], RMQ[16][2 * SIZE];
bool S[SIZE];
VP V[SIZE];

bool is_ancestor(int x, int y)
{
	return in[x] <= in[y] && out[x] >= out[y];
}
int T[SIZE], Enter;
void Dfs(int x)
{	
	S[x] = true;
	
	in[x] = ++indnow;
	niv[indnow] = niv[indnow - 1] + 1;
	T[niv[in[x]]] = x;
	
	minv[x][0] = Enter;
	nod[x][0] = T[niv[in[x] - 1]];
	for (int i = 1; (1 << i) <= N; ++i)
	{
		minv[x][i] = minv[x][i - 1];
		if (niv[in[x]] - (1 << (i - 1)) + 1 >= 1)
		{
			minv[x][i] = min(minv[x][i], minv[T[niv[in[nod[x][i - 1]] ]]][i - 1]);
			nod[x][i] = nod[T[niv[in[x]] - (1 << (i - 1))]][i - 1];
		}
	}
	
	for (VP::iterator it = V[x].begin(); it != V[x].end(); ++it)
		if (!S[it->first])
		{
			int auxEnter = Enter;
			Enter = it->second;
			Dfs(it->first);
			Enter = auxEnter;
		}
	out[x] = ++indnow;
	niv[indnow] = niv[in[x] - 1];
}

int main()
{
	ifstream fin("atac.in");
	ofstream fout("atac.out");
	
	for (int i = 2; i <= 64000; ++i)
		Log[i] = Log[i >> 1] + 1;
	
	fin >> N >> M >> P;
	for (int i = 2, Un, Vn; i <= N; ++i)
	{
		fin >> Un >> Vn;
		V[Un].push_back(make_pair(i, Vn));
		V[i].push_back(make_pair(Un, Vn));
	}
	Dfs(1);
	
	for (int i = 1; i <= 2 * N - 1; ++i)
		RMQ[0][i] = niv[i];
	for (int i = 1; (1 << i) <= 2 * N - 1; ++i)
		for (int j = 1; j <= 2 * N - 1; ++j)
		{
			RMQ[i][j] = RMQ[i - 1][j];
			if (j + (1 << (i - 1)) <= 2 * N - 1)
				RMQ[i][j] = min(RMQ[i][j], RMQ[i - 1][j + (1 << (i - 1))]);
		}
	
	fin >> X >> Y >> A >> B >> C >> D;
	for (int i = 1; i <= M; ++i)
	{
		if (X == Y) Z = 0;
		else
		{
			// Find LCA
			int nod1 = X, nod2 = Y, k = Log[abs(in[nod2] - in[nod1]) + 1];
			if (in[nod2] < in[nod1]) swap(nod1, nod2);
			int LCA = min(RMQ[k][in[nod1]], RMQ[k][in[nod2] - (1 << k) + 1]);
			
			// Find minim
			int nodn = X, newZ = INF;
			while (niv[in[nodn]] > LCA)
			{
				int aux = Log[niv[in[nodn]] - LCA];
				newZ = min(newZ, minv[nodn][aux]);
				nodn = nod[nodn][aux];
			}
			
			nodn = Y;
			while (niv[in[nodn]] > LCA)
			{
				int aux = Log[niv[in[nodn]] - LCA];
				newZ = min(newZ, minv[nodn][aux]);
				nodn = nod[nodn][aux];
			}
			
			Z = newZ;
		}
		
		if (i >= M - P + 1)  fout << Z << '\n';
		X = (X * A + Y * B) % N + 1;
		Y = (Y * C + Z * D) % N + 1;
	}
	
	fin.close();
	fout.close();
}