[BZOJ 3122][SDOI2013] 随机数生成器

Description

Description

Hint

\(p \in [2,10^9]\) 且为质数。

保证 \(X_1\)\(t\) 都是合法的页码。

Solution

根据递推关系,得:

\[X_2 \equiv a \cdot X_1 + b \pmod p \]

\[X_3 \equiv a \cdot X_2 + b \equiv a^2 \cdot X_1 + ab + b \pmod p \]

\[X_4 \equiv a \cdot X_3 + b \equiv a^3 \cdot X_1 + a^2b + ab + b \pmod p \]

\[\cdots \cdots \]

\[X_n \equiv a^{n-1} \cdot X_1 + b \times \sum\limits_{i=0}^{n-2} a^i \pmod p \]

我们发现 \(\sum_{i=0}^{n-2} a^i\) 就是一个等比数列求和,那么:

\[X_n \equiv a^{n-1} \cdot X_1 + b \times \dfrac{1 - a^{n-1}}{1 - a} \pmod p \]

\[X_n \equiv a^{n-1} \cdot X_1 - \dfrac{a^{n-1}}{1 - a} + \dfrac{b}{1 - a} \pmod p \]

\[X_n \equiv a^{n-1} \cdot (X_1 - \dfrac{1}{1 - a}) + \dfrac{b}{1 - a} \pmod p \]

\[a^{n-1} \cdot (X_1 - \dfrac{1}{1 - a}) \equiv X_n - \dfrac{b}{1 - a} \pmod p \]

\[a^{n-1} \equiv \dfrac{X_n - \dfrac{b}{1 - a}}{X_1 - \dfrac{1}{1 - a}} \pmod p \]

而这个 \(X_n\) 其实就是题目中的 \(t\) ,那么我们就是要求关于 \(n\) 方程

\[a^{n-1} \equiv \dfrac{t - \dfrac{b}{1 - a}}{X_1 - \dfrac{1}{1 - a}} \pmod p \]

的这些非负整数解(如果有解的话)。

我们惊喜地发现这里只有 \(n\) 一个未知数,那么显然可以用 BSGS (这里 \(p\) 为质数)求解。

但这里还有不少需要注意的细节:

  • \(t = X_1\) 时,答案为 \(0\)
  • \(a = 0\) 时,\(X_i \equiv b \pmod p\),其中 \(i > 1\)
  • \(a = 1\) 时,\(X_i \equiv b(i-1) \pmod p\),那么这就是一个线性同余方程,直接求逆元即可。

注意式子中的所有除法都是逆元。

#include<cmath>
#include<iostream>
#include<tr1/unordered_map>

typedef long long LL;
typedef std::tr1::unordered_map<LL,LL> HashMap;
using std::cin;
using std::cout;
using std::endl;

LL fastpow(LL a,LL b,LL c) {
	if(!b) return 1ll%c;
	LL t=fastpow(a,b>>1,c);
	if(b&1) return t*t%c*a%c;
	else return t*t%c;
}

LL inverse(LL a,LL p) {
	return fastpow(a,p-2,p);
}

HashMap f;
inline LL BSGS(LL a,LL b,LL p) {
	f.clear();
	LL m=ceil(sqrt(p));
	b%=p;
	for(LL i=1;i<=m;i++)
		(b*=a)%=p,f[b]=i;
	LL t=fastpow(a,m,p);
	b=1;
	for(LL i=1;i<=m;i++) {
		(b*=t)%=p;
		if(f.count(b))
			return (i*m-f[b]+p)%p;
	}
	return -1;
}

signed main() {
	LL p,a,b,x1,t;
	int Test_c;
	cin>>Test_c;
	while(Test_c--) {
		cin>>p>>a>>b>>x1>>t;
		if(x1==t) {
			cout<<1<<endl;
		} else if(a==0) {
			if(b==t) cout<<2<<endl;
			else cout<<-1<<endl;
		} else if(a==1) {
			if(b==0) cout<<-1<<endl;
			else cout<<((t-x1)%p+p)%p*inverse(b,p)%p+1<<endl;
		} else {
			LL tmp=((b*inverse(a-1,p)%p+t)%p)%p*inverse((b*inverse(a-1,p)%p+x1)%p,p)%p;
			LL ans=BSGS(a,tmp,p);
			if(ans==-1) cout<<-1<<endl;
			else cout<<ans+1<<endl;
		}
	}
}

猜你喜欢

转载自www.cnblogs.com/-Wallace-/p/12608686.html