题目链接
题目解法
首先尝试求出通项公式
多列出几项可以发现:
X
n
=
a
n
−
1
X
1
+
a
n
−
2
b
+
a
n
−
3
b
+
…
+
b
Xn=a^{n-1}X1+a^{n-2}b+a^{n-3}b+…+b
Xn=an−1X1+an−2b+an−3b+…+b
用等比数列求和公式可以得到:
X
n
=
a
n
−
1
X
1
+
a
n
−
1
−
1
a
−
1
b
Xn=a^{n-1}X1+\frac{a^{n-1}-1}{a-1}b
Xn=an−1X1+a−1an−1−1b
把所有
a
n
−
1
a^{n-1}
an−1 都合并在一起
X
n
=
a
n
−
1
(
X
1
+
b
a
−
1
)
−
b
a
−
1
Xn=a^{n-1}(X1+\frac{b}{a-1})-\frac{b}{a-1}
Xn=an−1(X1+a−1b)−a−1b
我们需要求最小的
n
n
n 满足
X
n
≡
t
(
m
o
d
p
)
Xn \equiv t\;(mod \; p)
Xn≡t(modp)
把
X
n
Xn
Xn 的表达式代入可得:
a
n
−
1
(
X
1
+
b
a
−
1
)
≡
t
+
b
a
−
1
(
m
o
d
p
)
a^{n-1}(X1+\frac{b}{a-1})\equiv t+\frac{b}{a-1}\;(mod \; p)
an−1(X1+a−1b)≡t+a−1b(modp)
把
a
n
−
1
a^{n-1}
an−1 单独放在左边:
a
n
−
1
≡
t
+
b
a
−
1
X
1
+
b
a
−
1
(
m
o
d
p
)
a^{n-1}\equiv \frac{t+\frac{b}{a-1}}{X1+\frac{b}{a-1}}\;(mod \; p)
an−1≡X1+a−1bt+a−1b(modp)
我们可以发现这个形式是
a
x
≡
b
(
m
o
d
p
)
a^x\equiv b \;(mod\;p)
ax≡b(modp)
p
p
p 是质数,与
a
a
a 互质,可以用
b
s
g
s
bsgs
bsgs 求解
同时这道题需要特判
a
=
0
a=0
a=0 和
a
=
1
a=1
a=1 的情况,这两类比较简单,但需要特殊考虑
另外需要考虑分母
X
1
+
b
a
−
1
X1+\frac{b}{a-1}
X1+a−1b 是否存在逆元
我们发现不存在逆元时
X
1
+
b
a
−
1
X1+\frac{b}{a-1}
X1+a−1b 是
p
p
p 的倍数,即
X
n
=
−
b
a
−
1
(
n
>
1
)
X^n=-\frac{b}{a-1}\;(n>1)
Xn=−a−1b(n>1)
这道题特判比较多,有点坑
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
inline int read(){
int FF=0,RR=1;
char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;
for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;
return FF*RR;
}
int bsgs(int a,int b,int p){
if(1%p==b%p) return 0;
int k=sqrt(p)+1;
unordered_map<int,int> hsh;
for(int i=0,j=b;i<k;i++)
hsh[j]=i,j=(LL)j*a%p;
int ak=1;
for(int i=1;i<=k;i++) ak=(LL)ak*a%p;
for(int i=1,j=1;i<=k;i++){
j=(LL)j*ak%p;
if(hsh.count(j)) return i*k-hsh[j];
}
return -2;
}
int qmi(int a,int b,int p){
int res=1;
for(;b;b>>=1){
if(b&1) res=(LL)res*a%p;
a=(LL)a*a%p;
}
return res;
}
void exgcd(int a,int b,int &x,int &y){
if(b==0){
x=1,y=0;
return;
}
int q=a/b,r=a%b;
exgcd(b,r,y,x);
y-=q*x;
}
void work(){
int p=read(),a=read(),b=read(),X1=read(),t=read();
if(a==0){//Xn=b(n>1)
if(X1==t) puts("1");
else if(b==t) puts("2");
else puts("-1");
}
else if(a==1){
if(b==0) puts(X1==t?"1":"-1");
else{
int x,y;
exgcd(b,p,x,y);
if(x<0) x+=p;
x=((LL)x*(t-X1)%p+p)%p;
printf("%d\n",x+1);
}
}
else{
int fm=(X1+(LL)b*qmi(a-1,p-2,p)%p)%p;
if(fm%p==0){
if(X1==t) puts("1");
else if((LL)-b*qmi(a-1,p-2,p)%p+p==t) puts("2");
else puts("-1");
}
else{
int fz=(t+(LL)b*qmi(a-1,p-2,p)%p)%p;
printf("%d\n",bsgs(a,(LL)fz*qmi(fm,p-2,p)%p,p)+1);
}
}
}
int main(){
int T=read();
while(T--) work();
return 0;
}