难得一个完全自己推出来的数论题,结果还因为特判挂了好几个星期,今天才把特判打出来A掉。
开始以为要求ax+bx≡c(mod p)这种形式的方程,然而并不会解,nc哥告诉我不是,我才想起来求通项公式(推了一节数学课推出来了)(mikufun推了一节物理课),
$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解即可。
然而这题不加特判会爆0……
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;
}
}