Cod sursa(job #596279)

Utilizator crushackPopescu Silviu crushack Data 16 iunie 2011 17:30:41
Problema Rsir Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.26 kb
#include <fstream>
using namespace std;
typedef long long ll;

const char IN[]="rsir.in",OUT[]="rsir.out";

ifstream fin(IN); 
ofstream fout(OUT);

//T0, T1, a, b, x, y, z, M si n
int T0,T1,a,b,x,y,z,M;
int Rez;
ll N;

inline int makeNumber(int x,int y){
	return x + M*y;
}

inline int next(int p)
{
	int T0= p%M , T1 = p/M;
	
	//Tn = a * Tn-2^2 + b * Tn-1^2 + x * Tn-2 + y * Tn-1 + z
	int T2 = (1LL * a * T0 * T0+ 1LL * b * T1 * T1 + 1LL * x * T0 + 1LL * y * T1 + z)% M;
	
	return makeNumber(T1,T2);
}

int getCycle(int v)
{
	int p1,p2;
	
	p1 = p2 = v;
	p1=next(p1),p2=next(next(p2));
	for (; p1!=p2 ;)
		p1=next(p1),p2=next(next(p2));
	for ( p1 = v ; p1!=p2 ; p1=next(p1) , p2 = next(p2) );
	
	return p1;
}

void solve()
{
	int c = getCycle(makeNumber(T0,T1)) , lcoada , lciclu , p;
	//printf("%d\n",c%M);
	
	for ( lcoada = 0 , p=makeNumber(T0,T1) ; p!=c ; p=next(p));
	for ( lciclu = 1 , p=next(c)  ; p!=c ; ++lciclu)
		p=next(p);
	
	if ( N > lcoada ) N-=lcoada;
	else
	{
		for ( p=makeNumber(T0,T1) ; N-- ; p=next(p));
		Rez=p%M;
		return;
	}
	
	N%=lciclu;
	for ( p=c ; N-- ; p=next(p));
	Rez=p%M;
}

int main()
{
	fin>>T0>>T1>>a>>b>>x>>y>>z>>M>>N;
	fin.close();
	
	solve();
	
	fout<<Rez<<"\n";
	
	return 0;
}