[NOI2012]随机数生成器

这是题目的原始式子(x_{n+1}=(ax_n+c)mod m)

我们将该式变成矩阵的形式

(egin{bmatrix}x_{n-1} cend{bmatrix}*egin{bmatrix}a 1\0 1end{bmatrix}=egin{bmatrix}x_{n} cend{bmatrix})

进行矩阵快速幂(egin{bmatrix}x_{0} cend{bmatrix}*egin{bmatrix}a 1\0 1end{bmatrix}^n)

然后输出(ans_{1,1}mod g)

注意:题目中(x_0leq10^{18})需用用到龟速乘

AC代码

#include<bits/stdc++.h>
#define int long long 
using namespace std;
const int N=5;
int x0,A,c,lpw,n,g;
struct Matrix
{
	int m[N][N];
}a,e;
void init()
{
	memset(a.m,0,sizeof(a.m));
	memset(e.m,0,sizeof(e.m));
	a.m[1][1]=x0,a.m[1][2]=c;
    e.m[1][1]=A,e.m[2][1]=e.m[2][2]=1;
}
int lowp(int x,int y)
{
	int ret=0;
	while(y)
	{
		if(y&1) ret=(ret+x)%lpw;
		y>>=1;
		x=(x+x)%lpw;
	}
	return ret;
}
Matrix mul(Matrix x,Matrix y)
{
	Matrix c;
	memset(c.m,0,sizeof(c.m));
	for(int i=1;i<=2;++i)
		for(int j=1;j<=2;++j)
			for(int k=1;k<=2;++k)	
				c.m[i][j]=(c.m[i][j]+lowp(x.m[i][k]%lpw,y.m[k][j]%lpw)%lpw)%lpw;
	return c;
}
int ksm(int p)
{
	while(p)
	{
		if(p&1) a=mul(a,e);
		e=mul(e,e);
		p>>=1;
	}
}
signed main()
{
	cin>>lpw>>A>>c>>x0>>n>>g;
	init();
	ksm(n);
	cout<<a.m[1][1]%g;		
	return 0;
}

上面的是AC的写法,还有一种繁琐一点的写法,但是不知道哪里错了,咕咕咕,有空的时候再来调吧

/*
@ author:pyyyyyy
1.Mulself时忘记把a更新了 
2.是在是找不出为什么a数组老出错了 
*/
#include<bits/stdc++.h>
#define int long long 
using namespace std;
int mod,mod1,n,aa,cc,x0;
int mul(int x,int y)//龟速乘 
{
	int ret=0;
	while(y)
	{
		if(y&1) ret=(ret+x)%mod;
		x=(x+x)%mod;
		y>>=1;
	}
	return ret%mod;
}
int f[3],a[3][3];
int Mul(int f[3],int a[3][3])
{
	int c[3];
	memset(c,0,sizeof(c));
	for(int i=0;i<2;++i)
		for(int j=0;j<2;++j)
			c[i]=(c[i]+mul(f[j],a[j][i]))%mod;
	memcpy(f,c,sizeof(c));
}
int Mulself(int a[3][3])
{
	int c[3][3];
	memset(c,0,sizeof(c));
	for(int i=0;i<2;++i)
		for(int j=0;j<2;++j)
			for(int k=0;k<2;++k)
				c[i][j]=(c[i][j]+mul(a[i][k],a[k][j]))%mod;
	memcpy(a,c,sizeof(c));
}
int Mulother(int w[3][3],int b[3][3])
{
	int c[3][3];
	memset(c,0,sizeof(c));
	for(int i=0;i<2;++i)
		for(int j=0;j<2;++j)
			for(int k=0;k<2;++k)
				c[i][j]=(c[i][j]+mul(w[i][k],b[k][j]))%mod;
	memcpy(w,c,sizeof(c));
}
void ksm(int x)
{
	int w[3][3];
	for(int i=0;i<2;++i)
		w[i][i]=1;
	while(x)
	{
		if(x&1) Mulother(w,a);
		Mulself(a);
		x>>=1;
	}
	memcpy(a,w,sizeof(w));
}
signed main()
{
	cin>>mod>>aa>>cc>>x0>>n>>mod1;	
	a[0][0]=aa,a[0][1]=1,a[1][0]=0,a[1][1]=1;
	f[0]=x0,f[1]=cc;

	ksm(n);
	for(int i=0;i<2;++i)
	{
		for(int j=0;j<2;++j)
			cout<<a[i][j]<<' ';
		cout<<'
';
	}
	Mul(f,a); 
	for(int i=0;i<2;++i) cout<<f[i]<<' ';
	cout<<endl;
	cout<<a[0][1]%mod1;
	return 0;
}
原文地址:https://www.cnblogs.com/pyyyyyy/p/12718662.html