# bzoj3122: [Sdoi2013]随机数生成器

[Sdoi2013]随机数生成器

$X_{i+1}=aX_i+b=a^2X_{i-1}+ab+b=a^3X_{i-2}+a^2b+ab+b$

$X_n=X_1*a^{n-1}+b+ab+...+a^{n-2}b$

$=X_1*a^{n-1}+b(a^0+a^1+...+a^{n-2})$

$=X_1*a^{n-1}+b\frac{a^{n-1}-1}{a-1}$

$=\frac{(a-1)X_1a^{n-1}}{a-1}+\frac{ba^{n-1}}{a-1}-\frac{b}{a-1}$

$=\frac{[(a-1)X_1+b]a^{n-1}}{a-1}-\frac{b}{a-1}$

$\frac{[(a-1)X_1+b]a^{n-1}}{a-1}-\frac{b}{a-1}\equiv t(mod p)$

$[(a-1)X_1+b]a^{n-1}\equiv (a-1)t+b (mod p)$

bsgs解即可。

 1         if(x1==t){cout<<1<<endl;continue;}
2         if(a==1)
3         {
4             if(!b){cout<<-1<<endl;continue;}
5             else  {cout<<(t-x1+p)*poww(b,p-2,p)%p+1<<endl;continue;}
6         }
7         if(a==0)
8         {
9             cout<<(b==t?2:-1)<<endl;
10             continue;
11         }        
#include<iostream>
#include<cstdio>
#include<cmath>
#include<map>
#define LL long long
#define int LL
using namespace std;
int T;
LL p,a,b,x1,t;
LL poww(LL a,LL b,LL p)
{
LL ans=1;
while(b)
{
if(b&1)ans=ans*a%p;
a=a*a%p;
b=b>>1;
}
return ans%p;
}
LL bsgs(LL a,LL b,LL p)
{
map<LL,LL>mp;mp.clear();
LL m=ceil(sqrt(p*1.0));
for(int j=0;j<=m;j++)
{
LL val=b*poww(a,j,p)%p;
mp[val]=j;
}
a=poww(a,m,p);
if(!a)return !b?0:-1;
for(int i=0;i<=m;i++)
{
LL val=poww(a,i,p);
LL j=mp.find(val)==mp.end()?-1:mp[val];
if(j>=0 && i*m-j>=0)return i*m-j;
}
return -1;
}
signed main()
{
cin>>T;
while(T--)
{
scanf("%lld%lld%lld%lld%lld",&p,&a,&b,&x1,&t);
if(x1==t){cout<<1<<endl;continue;}
if(a==1)
{
if(!b){cout<<-1<<endl;continue;}
else  {cout<<(t-x1+p)*poww(b,p-2,p)%p+1<<endl;continue;}
}
if(a==0)
{
cout<<(b==t?2:-1)<<endl;
continue;
}
LL tb,inv;
inv=poww((a-1)*x1%p+b,p-2,p);
inv=(inv%p+p)%p;
tb=((a-1)*t%p+b)%p*inv%p;
LL ans=bsgs(a,tb,p);
cout<<(ans==-1?-1:ans+1)%p<<endl;
}
}


posted @ 2019-07-14 11:01  Al_Ca  阅读(115)  评论(0编辑  收藏  举报