Cod sursa(job #480247)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 27 august 2010 02:48:17
Problema Iepuri Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 7.3 kb
#include<fstream>
#include<iostream>
#include<vector>
#include<iterator>

using namespace std;

template<typename T>
struct MatrixData
{
	long n,m;
	vector<vector<T> > v;
};

template<typename T>
class CMatrix
{
private:
	MatrixData<T> matData;
public:
	CMatrix()
	{
		matData.n=matData.m=1;
		matData.v.resize(matData.n);
		for(int i=0; i<matData.n; ++i)
		{
			matData.v[i].resize(matData.m);
			for(int j=0; j<matData.m; ++j)
				matData.v[i][j]=0;
		}
	}
	
	CMatrix(const long n, const long m)
	{
		matData.n=n;
		matData.m=m;
		matData.v.resize(matData.n);
		for(int i=0; i<matData.n; ++i)
		{
			matData.v[i].resize(matData.m);
			for(int j=0; j<matData.m; ++j)
				matData.v[i][j]=0;
		}
	}

	CMatrix(const vector<vector<T> > &v)
	{
		matData.n=v.size();
		matData.m=v[0].size();
		matData.v=v;
	}
	
	// access a matrix row
	const vector<T>& operator[] (const long index) const
	{
		return matData.v[index];
	}
	
	vector<T>& operator[] (const long index)
	{
		return matData.v[index];
	}
	
	// assign operator
	const bool operator= (const CMatrix& mat)
	{
		matData.n=mat.matData.n;
		matData.m=mat.matData.m;
		matData.v=mat.matData.v;
		return true;
	}
	
	const bool operator= (const MatrixData<T>& mdata)
	{
		matData.n=mdata.n;
		matData.m=mdata.m;
		matData.v=mdata.v;
	}
	
	// multiply operator
	
	// scale multiply
	const CMatrix<T>& operator*(const T& scalar) const
	{
		static CMatrix mat;
		mat=CMatrix(matData.n, matData.m);
		for(int i=0; i<mat.matData.n; ++i)
		{
			for(int j=0; j<mat.matData.m; ++j)
				mat.matData.v[i][j]=matData.v[i][j]*scalar;
		}
		return mat;
	}
	
	// matrix multiply
	const CMatrix<T>& operator*(const CMatrix<T>& matrix) const
	{
		static CMatrix<T> matres;
		if(matData.m!=matrix.matData.n)
		{
			return matres;
		}
		matres=CMatrix(matData.n, matrix.matData.m);
		
		for(int k=0; k<matData.m; ++k)
		{
			for(int i=0; i<matData.n; ++i)
			{	
				for(int j=0; j<matrix.matData.m; ++j)
				{
					matres.matData.v[i][j]=matres.matData.v[i][j]+
						matData.v[i][k] * matrix.matData.v[k][j];
				}
			}
		}
		return matres;
	}
	
	// sum operator
	const CMatrix<T>& operator+(const CMatrix<T>& matrix) const
	{
		static CMatrix<T> matres;
		if(matData.n!=matrix.matData.n || matData.m!=matrix.matData.m)
		{
			return matres;
		}
		matres=CMatrix(matData.n, matData.m);
		for(int i=0; i<matData.n; ++i)
		{	
			for(int j=0; j<matData.m; ++j)
			{
				matres.matData.v[i][j]=matData.v[i][j]+matrix.matData.v[i][j];
			}
		}
		return matres;
	}
	
	const bool operator+=(const CMatrix<T>& matrix)
	{
		if(matData.n!=matrix.matData.n || matData.m!=matrix.matData.m)
			return false;
		for(int i=0; i<matData.n; ++i)
		{	
			for(int j=0; j<matData.m; ++j)
			{
				matData.v[i][j]=matData.v[i][j]+matrix.matData.v[i][j];
			}
		}
		return true;
	}

	// subtraction operator
	const CMatrix<T>& operator-(const CMatrix<T>& matrix) const
	{
		static CMatrix<T> matres;
		if(matData.n!=matrix.matData.n || matData.m!=matrix.matData.m)
		{
			return matres;
		}
		matres=CMatrix(matData.n, matData.m);
		for(int i=0; i<matData.n; ++i)
		{	
			for(int j=0; j<matData.m; ++j)
			{
				matres.matData.v[i][j]=matData.v[i][j]-matrix.matData.v[i][j];
			}
		}
		return matres;
	}
	
	const bool operator-=(const CMatrix<T>& matrix)
	{
		if(matData.n!=matrix.matData.n || matData.m!=matrix.matData.m)
			return false;
		for(int i=0; i<matData.n; ++i)
		{	
			for(int j=0; j<matData.m; ++j)
			{
				matData.v[i][j]=matData.v[i][j]-matrix.matData.v[i][j];
			}
		}
		return true;
	}
	
	// modulo operator
	const CMatrix<T>& operator%(const long mod) const
	{
		static CMatrix<T> matres;
		matres=CMatrix(matData.n, matData.m);
		for(int i=0; i<matData.n; ++i)
		{	
			for(int j=0; j<matData.m; ++j)
			{
				matres.matData.v[i][j]=matData.v[i][j]%mod;
			}
		}
		return matres;
	}
	
	// adjunct matrix
	const CMatrix<T>& adj() const
	{
		static CMatrix<T> matadj;
		matadj=CMatrix(matData.n,matData.n);
		if(matData.n!=matData.m)
			return matadj;
		
		if(matData.n==3)
		{
			matadj.matData.v[0][0]=matData.v[1][1]*matData.v[2][2]-
								   matData.v[1][2]*matData.v[2][1];
			matadj.matData.v[1][0]=-(matData.v[1][0]*matData.v[2][2]-
								     matData.v[1][2]*matData.v[2][0]);
			matadj.matData.v[2][0]=matData.v[1][0]*matData.v[2][1]-
								   matData.v[1][1]*matData.v[2][0];
								   
			matadj.matData.v[0][1]=-(matData.v[0][1]*matData.v[2][2]-
								     matData.v[0][2]*matData.v[2][1]);
			matadj.matData.v[1][1]=matData.v[0][0]*matData.v[2][2]-
								   matData.v[0][2]*matData.v[2][0];
			matadj.matData.v[2][1]=-(matData.v[0][0]*matData.v[2][1]-
								     matData.v[0][1]*matData.v[2][0]);
								   
			matadj.matData.v[0][2]=matData.v[0][1]*matData.v[1][2]-
								   matData.v[0][2]*matData.v[1][1];
			matadj.matData.v[1][2]=-(matData.v[0][0]*matData.v[1][2]-
								     matData.v[0][2]*matData.v[1][0]);
			matadj.matData.v[2][2]=matData.v[0][0]*matData.v[1][1]-
								   matData.v[0][1]*matData.v[1][0];
		}
		return matadj;
	}
	
	// determinant
	const T det() const
	{
		if(matData.n!=matData.m)
			return 0;
		switch(matData.n)
		{
			case 2:
			{
				return matData.v[0][0]*matData.v[1][1]-
					   matData.v[0][1]*matData.v[1][0];
			}; break;
			case 3:
			{
				return matData.v[0][0]*matData.v[1][1]*matData.v[2][2]+
					   matData.v[0][1]*matData.v[1][2]*matData.v[2][0]+
					   matData.v[0][2]*matData.v[1][0]*matData.v[2][1]-
					   matData.v[0][0]*matData.v[1][2]*matData.v[2][1]-
					   matData.v[0][1]*matData.v[1][0]*matData.v[2][2]-
					   matData.v[0][2]*matData.v[1][1]*matData.v[2][0];
			}; break;
		}
		return 0;
	}

	const long GetNumRows() const
	{
		return matData.n;
	}
	
	const long GetNumCols() const
	{
		return matData.m;
	}
	
	void Clear()
	{
		for(int i=0; i<matData.n; ++i)
		{
			matData.v[i].clear();
		}
		matData.v.clear();
	}
	
	~CMatrix()
	{
		Clear();
	}
};

const int MODULO=666013;

int main()
{
	int X,Y,Z,A,B,C,T,N;
	fstream fin("iepuri.in",fstream::in);
	fstream fout("iepuri.out",fstream::out);
	int i,j;
	//vector<vector<long long> > va, vsol;
	CMatrix<long long> a(3,3), sol(3,3);
	fin>>T;
	for(i=0; i<T; ++i)
	{
		fin>>X>>Y>>Z>>A>>B>>C>>N;
		
		a[1][1]=a[1][2]=a[2][0]=a[2][2]=0;
		a[1][0]=a[2][1]=1;
		a[0][0]=A;
		a[0][1]=B;
		a[0][2]=C;
		sol[0][1]=sol[0][2]=sol[1][0]=sol[1][2]=sol[2][0]=sol[2][1]=0;
		sol[0][0]=sol[1][1]=sol[2][2]=1;
		N-=2;
		while(N)
		{
			if( N & 1 )
			{
				sol=(sol*a)%MODULO;
			}
			a=(a*a)%MODULO;
			N>>=1;
		}
		fout<<(sol[0][0]*Z+sol[0][1]*Y+sol[0][2]*X)%MODULO<<endl;
	}
	
	fin.close();
	fout.close();
	/*int n=3,m=3;
	vector<vector<long> > v,vt;
	v.resize(n);
	for(int i=0; i<n; ++i)
	{
		v[i].resize(m);
	}
	
	for(int i=0; i<n; ++i)
	{
		for(int j=0; j<m; ++j)
			v[i][j]=7;
	}

	CMatrix<long> mat1(v),mat2(3,3),rez(3,3);
	
	mat2[0][0]=-2;
	mat2[0][1]=2;
	mat2[0][2]=-3;
	mat2[1][0]=-1;
	mat2[1][1]=1;
	mat2[1][2]=3;
	mat2[2][0]=2;
	mat2[2][1]=0;
	mat2[2][2]=-1;

	cout<<mat2.det()<<endl;
	rez=mat2.adj()%3;
	
	for(int i=0; i<rez.GetNumRows(); ++i)
	{
		for(int j=0; j<rez.GetNumCols(); ++j)
		{
			cout<<rez[i][j]<<" ";
		}
		cout<<"\n";
	}*/
	return 0;
}