Cod sursa(job #789965)

Utilizator danalex97Dan H Alexandru danalex97 Data 19 septembrie 2012 22:37:34
Problema Robotei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.84 kb
#include <fstream>
#include <vector>
#include <queue>
using namespace std;

const int Xmax = 1000010;
const int Nmax = 1010;

int X,Y,Mx,My,N,M,Ox,Oy;

vector< int > A[Xmax],B[Xmax];
int Go[Nmax][Nmax];
int Come[Nmax][Nmax];
int Sol[Xmax>>1];

int MatX[Nmax],MatY[Nmax];

ifstream F("robotei.in");
ofstream G("robotei.out");

inline int Make( int x , int y )
{
	return x*Mx+y;
}

#define Rx first
#define Ry second

inline pair<int,int> Rever( int x )
{
	return make_pair( x/Mx , x-(x/Mx)*Mx );
}

inline pair<int,int> Next( int i ,int j )
{
	return make_pair( ( (i*i)%Mx + Ox )%Mx , ( (j*j)%My + Oy )%My )	;
}

inline int Next_x(int x)
{
	return ( (x*x)%Mx + Ox )%Mx ;
}

inline int Next_y(int y)
{
	return ( (y*y)%My + Oy )%My; 
}

void Bfs_go( int Nod )
{
	vector<int>::iterator it;
	
	queue< pair<int,int> > Q;
	Q.push( make_pair( Nod , 0 ) );
	
	while ( Q.size() )
	{
		Nod = Q.front().Rx;
		int Cost = Q.front().Ry + 1;
		Q.pop();
		
		for (it=A[Nod].begin();it!=A[Nod].end();++it)
		{
			pair<int,int> R = Rever(*it);
			if ( Go[R.Rx][R.Ry] == 0 )
				continue;
			Go[R.Rx][R.Ry] = Cost;
			Q.push( make_pair( *it , Cost ) );
		}
	}
}

void Bfs_come( int Nod )
{
	vector<int>::iterator it;
	
	queue< pair<int,int> > Q;
	Q.push( make_pair( Nod , 0 ) );
	
	while ( Q.size() )
	{
		Nod = Q.front().Rx;
		int Cost = Q.front().Ry + 1;
		Q.pop();
		
		for (it=B[Nod].begin();it!=B[Nod].end();++it)
		{
			pair<int,int> R = Rever(*it);
			if ( Come[R.Rx][R.Ry] == 0 )
				continue;
			Come[R.Rx][R.Ry] = Cost;
			Q.push( make_pair( *it , Cost ) );
		}
	}
}

int Solve(int x,int y,int Val,int Co)
{
	int Steps=M-1;
	int Ciclu=Go[x][y]+Come[x][y];
	
	if ( x==X && y==Y )
	{
		++Co;
	}
	else
	{
		Steps-=Come[x][y];
		if ( Steps > -1 ) ++Co;
	}
	
	Co += Steps / Ciclu;
	
	return Co;
}

int main()
{
	F>>N>>M>>X>>Y;
	F>>Mx>>My>>Ox>>Oy;
	
	Ox%=Mx, Oy%=My;
	
	for (int i=1;i<=N;++i)
		for (int j=1;j<=N;++j)
		{
			pair<int,int> Urm = Next( i , j );
			int x = Make( i , j );
			int y = Make( Urm.Rx , Urm.Ry );
			A[x].push_back( y );
			B[y].push_back( x );
		}
	
	if ( X>=Mx || Y>=My )
	{
		G<<"1\n";
		return 0;
	}
	
	int Start = Make( X , Y );
	
	Go[X][Y]=1;
	Come[X][Y]=1;
	
	Bfs_go( Start );
	Bfs_come( Start );
	
	Come[X][Y]=0;
	
	for (int i=0;i<N;++i) ++MatX[ Next_x( i ) ];
	for (int i=0;i<N;++i) ++MatY[ Next_y( i ) ];
	
	int NextX = Next_x( X );
	int NextY = Next_y( Y );
	for (int i=0;i<Mx;++i)
		for (int j=0;j<Mx;++j)
			if ( i!=NextX || j!=NextY )
				Solve( i , j , MatX[i]*MatY[j] , ( i==X && j==Y ) ? 0 : 1 );
			else
			{
				Solve( i , j , MatX[i]*MatY[j]-1 , ( i==X && j==Y ) ? 0 : 1  );
				Solve( i , j , 1 , 1 );
			}
	for (int i=0;i<M;++i)
		if ( Sol[i]>0 )
			G<<i<<' '<<Sol[i];
	
	F.close();
	G.close();
	return 0;
}