题目链接

\(BSGS\)


题目大意:定义\(X_i = aX_{i-1}+b\),给定\(X_1\),求最小的\(n\)使得\(X_n \equiv t(mod \; p)\)

分析:大力化简柿子

\[X_1=X_1 \]

\[X_2 = aX_1+b \]

\[X_3=a^2X_1+ab + b \]

\[X_4 = a^3X_1+a^2b+ab+b \]

观察得出\(X_n=a^{n-1}X_1+b\sum_{i=0}^{n-2}a^i\)

发现后面是一个等比数列求和

\(S=\sum_{i=0}^{n-2}a^i\)

\(\therefore aS=\sum_{i=1}^{n-1}a^i\)

\(\therefore (a-1)S=a^{n-1}-1\)

\(\therefore S= \sum_{i=0}^{n-2}=a^{n-1}-1\)

继续化简:

\(X_n=a^{n-1}X_1+b \cdot \frac{a^{n-1}-1}{a-1}\)

\(X_n=a^{n-1}X_1+a^{n-1} \cdot \frac{b}{a-1} - \frac{b}{a-1}\)

\(X_n=a^{n-1}(X_1+\frac{b}{a-1})-\frac{b}{a-1}\)

\(X_n=a^{n-1}(X_1+\frac{b}{a-1})-\frac{b}{a-1} \equiv t(mod \; p)\)

\(\therefore a^{n-1}(X_1+\frac{b}{a-1}) \equiv t + \frac{b}{a-1}\)

\(\therefore a^{n-1} \equiv \frac{t+\frac{b}{a-1}}{X_1+\frac{b}{a-1}}\)

直接\(BSGS\)求解即可,模意义下用费马小定理求一下逆元

然后有一些毒瘤的细节

  • \(Detail\;1\)\(X_1=t\)\(ans=1\)
  • \(Detail\;2\)\(a=0\)时,\(X_1=X_1,X_n \equiv b(n \neq 2)\)
  • \(Detail\;3\)\(a=1\)时,\(X_n=X_1+b(n-1)\),有\(X_1+b(n-1) \equiv t(mod\;p)\),\(n=\frac{t-X_1}{b}+1\),这里用裴蜀定理判断一下有没有解
#include <cstdio>
#include <cmath>
#include <unordered_map>
using namespace std;
typedef long long ll;
ll p,a,b,X0,t,T;
namespace BSGS{
	unordered_map<ll,int> mp;
	inline ll qpow(ll a,ll b,ll mod){
		ll res = 1,base = a;
		while(b){
			if(b & 1)res = res * base % mod;
			base = base * base % mod;
			b >>= 1;
		}
		return res;
	}
	inline ll gcd(ll a,ll b){
		return !b ? a : gcd(b,a % b);
	}
	inline ll inv(ll x,ll p){
		return qpow(x,p - 2,p);
	}
	inline ll bsgs(ll y,ll z,ll p){
		ll m = sqrt(p) + 1;mp.clear();
		y %= p,z %= p;
		if(y % p == 0 && z)return -1;
		for(ll t = z,i = 0;i < m;i++,t = t * y % p)mp[t] = i;
		for(ll w = qpow(y,m,p),t = w,i = 1;i <= m + 1;i++,t = t * w % p)
			if(mp.find(t) != mp.end())return i * m - mp[t];
		return -1;
	}
}using namespace BSGS;
inline void solve(){
	scanf("%lld %lld %lld %lld %lld",&p,&a,&b,&X0,&t);
	if(X0 == t){
		printf("%d\n",1);
		return;
	}
	if(a == 0){
		if(b == t)printf("2\n");
		else printf("-1\n");
		return;
	}
	if(a == 1){
		ll d = gcd(b,p);
		if((t - X0) % d)printf("-1\n");
		else printf("%lld\n",1ll * (((t - X0) % p) + p) % p * inv(b % p,p) % p + 1);
		return;
	}
	ll z = t + b * inv(a - 1,p);z %= p;
	z *= inv((X0 + (b * inv(a - 1,p)) % p) % p,p);z %= p;
	ll ans = bsgs(a,z,p);
	if(ans == -1)printf("-1\n");
	else printf("%lld\n",ans + 1);
}
int main(){
	scanf("%lld",&T);
	while(T--)solve();
	return 0;
}

相关文章:

  • 2021-11-30
  • 2022-01-30
  • 2021-12-20
  • 2021-10-31
  • 2021-11-30
  • 2021-11-23
猜你喜欢
  • 2021-11-30
  • 2021-11-05
  • 2022-12-23
  • 2021-11-30
  • 2021-06-01
  • 2021-11-30
  • 2021-06-27
相关资源
相似解决方案