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;
}
}
}