LOJ 2670 随机数生成器

矩阵乘法

\(\begin{bmatrix} x_0 & 1 \end{bmatrix} \ast \begin{bmatrix} a & 0\\ c & 1 \end{bmatrix}\)

O(1)快速乘,见代码

#include <cstdio>

long long MOD;

long long sr;
long long sum(long long a, long long b){
	sr=a+b;
	if(sr>=MOD)	sr-=MOD;
	return sr;
}

long long mul(long long a, long long b){
	long long k=(long long)((1.0L*a*b)/(1.0L*MOD));
	long long ret=a*b-k*MOD;
	if(ret<0LL)	ret+=MOD;
	return ret;
}

long long A, C, X, N, G;

struct Mat{
	long long n[2][2];
} Zero, One, Init;

Mat operator * (Mat A, Mat B){
	Mat ret=Zero;
	for(int i=0;i<2;++i)
		for(int j=0;j<2;++j)
			for(int k=0;k<2;++k)
				ret.n[i][k]=sum(ret.n[i][k], mul(A.n[i][j], B.n[j][k]));
	return ret;
}

Mat Pow(Mat a, long long k){
	Mat ret=One, t=a;
	while(k>0LL){
		if(k&1LL)	ret=ret*t;
		t=t*t;
		k>>=1;
	}
	return ret;
}

int main(){
	
	scanf("%lld%lld%lld%lld%lld%lld", &MOD, &A, &C, &X, &N, &G);
	
	One.n[0][0]=One.n[1][1]=1LL;
	Init.n[0][0]=A%MOD;Init.n[0][1]=0LL;
	Init.n[1][0]=C%MOD;Init.n[1][1]=1LL;
	
	Init=Pow(Init, N);
	
	long long Ans=sum(mul(Init.n[0][0], X), Init.n[1][0]);
	printf("%lld\n", Ans%G);
	
	return 0;
}
posted @ 2018-11-28 15:25  Pickupwin  阅读(166)  评论(0编辑  收藏  举报