洛咕 P3306 [SDOI2013]随机数生成器
大力推式子???
(X_{i}=underbrace{a(a(cdots(a(a}_{i-1个a}X_1+b)))cdots))
(=b+ba+ba^2+cdots+ba^{i-3}+ba^{i-2}+X_1a^{i-1}equiv t( ext{mod }p))
(bfrac{a^{i-1}-1}{a-1}+a^{i-1}x_1equiv t( ext{mod }p))
拆分一波,提出(a^{i-1})
((X_1+frac{b}{a-1})a^{i-1}equiv frac{b}{a-1}+t( ext{mod }p))
(a^{i-1}equiv frac{frac{b}{a-1}+t}{frac{b}{a-1}+X_1} ( ext{mod }p))
然后bsgs即可。
这题还要加一堆特判。。。懒得写了。。。丧心病狂
#include<bits/stdc++.h>
#define il inline
#define vd void
typedef long long ll;
il int gi(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')f=-1;
ch=getchar();
}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return x*f;
}
ll T,mod,a,b,X1,t;
il ll pow(ll a,ll b){
ll ret=1;
while(b){
if(b&1)ret=ret*a%mod;
a=a*a%mod;b>>=1;
}
return ret;
}
std::map<ll,ll>M;
int main(){
#ifndef ONLINE_JUDGE
freopen("3306.in","r",stdin);
freopen("3306.out","w",stdout);
#endif
T=gi();
while(T--){
mod=gi(),a=gi(),b=gi(),X1=gi(),t=gi();
ll B=(t+b*pow(a-1,mod-2)%mod)%mod,A=(B-t+X1+mod)%mod,C=B*pow(A,mod-2)%mod;
ll s=sqrt(mod)+1,ans=1e18;
if(t==X1){puts("1");continue;}
if(a==1){
A=b,B=(t-X1+mod)%mod;
if(b==0||A%std::__gcd(B,mod))puts("-1");
else printf("%lld
",((t-X1+mod)*pow(b,mod-2)%mod)%mod+1);
continue;
}
if(a==0){printf("%lld
",b==t?2ll:(-1ll));continue;}
M.clear();
for(ll i=0,j=C%mod;i<s;++i,j=j*a%mod)M[j]=i;
ll P=pow(a,s);
for(ll i=1,j=P;i<=s+1;++i,j=j*P%mod)if(M.find(j)!=M.end())ans=std::min(ans,i*s-M[j]);
if(ans==1e18)puts("-1");
else printf("%lld
",ans+1);
}
return 0;
}