Cod sursa(job #2856)

Utilizator wefgefAndrei Grigorean wefgef Data 19 decembrie 2006 16:08:57
Problema Robotei Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.27 kb
#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

#define x first
#define y second
#define mp(a, b) make_pair(a, b)
#define pb(v, a) v.push_back(a)
#define sz(a) a.size()

#define Xmax 1024
#define Mmax 1024*1024

vector< pair<int, int> > vec[Xmax][Xmax];
pair<int, int> Q[Xmax*Xmax];
int c[Xmax][Xmax], rez[Mmax], frec[Mmax];
int n, m, start, stop, X, Y, offx, offy, ciclu;

void readdata()
{
	freopen("robotei.in", "r", stdin);
	freopen("robotei.out", "w", stdout);
	
	scanf("%d %d %d %d %d %d %d %d", &n, &m, &start, &stop, &X, &Y, &offx, &offy);
}

void afla_ciclu()
{
	int nr = 0, ax = start, bx = stop;
	do
	{
		ax = (ax*ax + offx) % X;
		bx = (bx*bx + offy) % Y;
		++nr;
		if (nr > X*Y+2) break;
	}
	while (ax != start || bx != stop);
	if (nr > X*Y+2) ciclu = 0;
	else ciclu = nr;
	
}

void solve()
{
	int i, j, ii, jj, cont, cap, k, lim, nr, sum = 0;
	
	afla_ciclu();
	//construieste graful invers
	for (i = 0; i < X; ++i)
	for (j = 0; j < Y; ++j)
	{
		ii = (i*i + offx) % X;
		jj = (j*j + offy) % Y;
		pb(vec[ii][jj], mp(i, j));
	}
	//caz particular cand poz initiale sunt prea mari
	if (start >= X || stop >= Y)
	{
		rez[0] = n*n-1;
		rez[1] = 1;
		return;
	}
	//BFS
	cont = cap = 1;
	Q[1] = mp(start, stop);
	while (cap <= cont)
	{
		i = Q[cap].x;
		j = Q[cap].y;
		lim = sz(vec[i][j]);
		for (k = 0; k < lim; ++k)
		{
			ii = vec[i][j][k].x;
			jj = vec[i][j][k].y;
			if (c[ii][jj] == 0)
			{
				c[ii][jj] = c[i][j]+1;
				Q[++cont] = mp(ii, jj);
			}
		}
		++cap;
	}

	nr = ((n)/X)*((n)/Y);
	for (i = 0; i < X; ++i)
	for (j = 0; j < Y; ++j)
		frec[c[i][j]] += nr;
	--frec[c[start][stop]];
	
	for (i = 0; i < (n)%X; ++i)
	for (j = 0; j < Y; ++j)
		frec[c[i][j]] += n/Y;
		
	for (j = 0; j < (n)%Y; ++j)
	for (i = 0; i < X; ++i)
		frec[c[i][j]] += n/X;
		
	for (i = 0; i < (n)%X; ++i)
	for (j = 0; j < (n)%Y; ++j)
		frec[c[i][j]]++;
		
	frec[0] = 1;
	
	return;
	for (i = 0; i < 1000000; ++i)
	if (m-i >= 0)
	{
		rez[1+(m-i)/ciclu] += frec[i];
		sum += frec[i];
	}
	rez[0] = n*n-sum;
}

void writedata()
{
	int i;
	for (i = 0; i <= m; ++i)
	if (rez[i])
		printf("%d %d\n", i, rez[i]);
}

int main()
{
	readdata();
	solve();
	writedata();
	return 0;
}