Cod sursa(job #268691)

Utilizator andrei-alphaAndrei-Bogdan Antonescu andrei-alpha Data 1 martie 2009 17:34:25
Problema Robotei Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.12 kb
using namespace std;

#include <set>
#include <map>
#include <list>
#include <deque>
#include <stack>
#include <queue>
#include <cmath>
#include <cstdio>
#include <vector>
#include <string>
#include <bitset>
#include <utility>
#include <algorithm>

#define pb push_back
#define sz size
#define f first
#define s second
#define II inline
#define ll long long
#define db double
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define all(v) v.begin() , v.end()
#define CC(v) memset((v),0,sizeof((v)))
#define CP(v,w) memcpy((v),(w),sizeof((w)))
#define mp make_pair

#define IN "robotei.in"
#define OUT "robotei.out"
#define N_MAX 1<<10
#define M_MAX 1<<20
#define oo 1684300900

typedef vector<int> VI;
typedef pair<int,int> pi;
typedef vector<string> VS;

int Di,K,X,Y,N,M,setX,setY;
int Lp[N_MAX][N_MAX],Ln[N_MAX][N_MAX];
int D[N_MAX][N_MAX],Xp[N_MAX][N_MAX],Yp[N_MAX][N_MAX];
int C[N_MAX],L[N_MAX],S[M_MAX];

II void scan()
{
	freopen(IN,"r",stdin);
	freopen(OUT,"w",stdout);
	scanf("%d%d%d%d%d%d%d%d",&Di,&K,&X,&Y,&N,&M,&setX,&setY);
	--N,--M,--Di;
}

II void next(pi &x)
{
	x.f = (x.f*x.f + setX) % (N+1);
	x.s = (x.s*x.s + setY) % (M+1);
}

II void make(int x,int y)
{
	int lg(0),poz(-1),per(1),poz2(-1);
	pi m1,m2;
	
	m1 = m2 = mp(x,y);
	next(m1);next(m2);next(m2);
	bool ok(false);
	for(;m1 != m2;next(m1),next(m2),next(m2) )
	{
		pi m3(m2);
		next(m3);
		if(Lp[m1.f][m1.s]) 
		{
			ok = true;
			break;
		}
		if(Lp[m2.f][m2.s])
		{
			m1 = m2;
			ok = true;
			break;
		}	
		if(Lp[m3.f][m3.s])
		{
			m1 = m3;
			ok = true;
			break;
		}	
	}	
	if(ok)
	{
		m2 = mp(x,y);
		for(;m2 != m1;next(m2),++lg)
			if( mp(X,Y) == m2)
				poz = lg;
		
		m2 = mp(x,y);
		for(;m2 != m1;next(m2) )
		{
			Lp[m2.f][m2.s] = Lp[m1.f][m1.s];
			Ln[m2.f][m2.s] = Ln[m1.f][m1.s] + lg;
			Xp[m2.f][m2.s] = Xp[m1.f][m1.s];
			Yp[m2.f][m2.s] = Yp[m1.f][m1.s];
			if(poz>=0)
				D[m2.f][m2.s] = poz--;
			else
				D[m2.f][m2.s] = oo;
			if(D[m1.f][m1.s] < 1<<20)
				D[m2.f][m2.s] = D[m1.f][m1.s] + lg;
			--lg;
		}
		return;
	}	
	
	m2 = m1;
	for(next(m2);m2 != m1;next(m2),++per)
		if( mp(X,Y) == m2)
			poz2 = per;
	if(mp(X,Y) == m1)
		poz2 = 0;
	for(m2 = mp(x,y);m2 != m1;next(m2) )
	{
		++lg;
		if(m2 == mp(X,Y) )
			poz = lg-1;
	}
	for(m2 = mp(x,y);m2 != m1;next(m2) )
	{
		Xp[m2.f][m2.s] = m1.f;
		Yp[m2.f][m2.s] = m1.s;
		if(poz>=0)
			D[m2.f][m2.s] = poz--;
		else
			D[m2.f][m2.s] = oo;
		Ln[m2.f][m2.s] = lg--;
		Lp[m2.f][m2.s] = per;
	}
	
	m2 = m1;
	Lp[m1.f][m1.s] = per;
	Xp[m1.f][m1.s] = m2.f;
	Yp[m1.f][m1.s] = m2.s; 
	if(poz2==-1)
		ok = true;
	if(!ok)
		D[m2.f][m2.s] = poz2--;
	int aux = per;
	for(next(m2);m2 != m1;next(m2) )
	{
		if(poz2<0)
			poz2 = per-1;
		if(!ok)
			D[m2.f][m2.s] = poz2--;
		Xp[m2.f][m2.s] = m1.f;
		Yp[m2.f][m2.s] = m1.s;
		Ln[m2.f][m2.s] = --aux;
		Lp[m2.f][m2.s] = per;
	}		
}

II void count()
{
	FOR(i,0,N)
	FOR(j,0,M)
	{
		int nr(0),k(K),mul = L[i] * C[j];
		if(!mul)
			continue;
		if(k >= D[i][j] && Ln[i][j] > D[i][j])
			++nr;
		k -= min(K,Ln[i][j]);
		
		int ii(Xp[i][j]),jj(Yp[i][j]);
		if(!Ln[i][j])
			ii=i,jj=j;
		
		if(D[ii][jj] < Lp[ii][jj])
		{
			nr += k / Lp[ii][jj];
			k -= k / Lp[ii][jj] * Lp[ii][jj];
			if(k >= D[ii][jj])
				++nr;
		}
		if(nr==2)
		{
			int debug = 1;
		}	
		S[nr] += mul;
	}	
}

II void solve()
{
	memset(D,100,sizeof(D));
	
	FOR(i,0,N)
	FOR(j,0,M)
		if(!Lp[i][j])
			make(i,j);
	
	FOR(i,0,max(N,M))
		L[i] = C[i] = 1;
	count();
	--K;
	
	CC(L);CC(C);
	FOR(i,N+1,Di)
		++L[(i*i + setX) % (N+1)];
	FOR(j,0,Di)
		++C[(j*j + setY) % (M+1)];	
	count();	
	CC(L);CC(C);
	
	FOR(i,0,N)
		++L[(i*i + setX) % (N+1)];
	FOR(j,M+1,Di)
		++C[(j*j + setY) % (M+1)];	
	count();
	
	FOR(i,0,K+2)
		if(S[i])
			printf("%d %d\n",i,S[i]);
/*	
	FOR(i,0,Di) 
    FOR(j,0,Di) 
    { 
        pi m1 = mp(i,j); 
        printf("[%d,%d] ",m1.f,m1.s); 
        FOR(j,1,K+1) 
        { 
            next(m1); 
            printf("[%d,%d] ",m1.f,m1.s); 
        }    
        printf("\n"); 
    }
*/		
}

int main()
{
	scan();
	solve();
	return 0;
}