题目地址:
Dashboard - The 15th Jilin Provincial Collegiate Programming Contest - Codeforces
这个题意思就是给你5个数:a , b ,m, X0, X;
Xn+1=(a*Xn+b)mod m ,通过这样是可以构造出来一个数组,问你X是不是在Xn这个数组中,
首先对题进行化简,可以得到:
这样就可以看出是用bsgs算法:
首先对a ,b,x,x0,进行特判情况。然后就直接上手bsgs,右边是可能是一个分数,所以我们可以求出它的逆元,利用费马小定理,右式化简可以得到的是(x*(a-1)+b)/(x0*(a-1)+b).利用费马小定理求取它的逆元pp,然后式子就演变成了a^n ≡ pp(mod m),然后用bsgs算法求一下就可以了。
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e6+10;
#define lmw ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int x,y,z;
int a,b,p,x0,xx;
map<int,int>ma;
int power(int x,int y){
x%=p;
int res=1;
while(y){
if(y&1) res=res*x%p;
x=x*x%p;
y/=2;
}
return res%p;
}
void bsgs(){
if(y==0&&z==0){
cout<<"YES\n";
return;
}
if(y==0&&z!=0){
cout<<"NO\n";
return;
}
int m=ceil(sqrt(p));
ma.clear();
int t=z%p;
ma[t]=0;
for(int j=1;j<=m;j++){
t=t*y%p;
ma[t]=j;
}
t=1;
t%=p;
int mi=power(y,m);
for(int i=1;i<=m;i++){
t=t*mi%p;
if(ma.count(t)){
x=i*m-ma[t];
x=(x%p+p)%p;
cout<<"YES\n";
return ;
}
}
cout<<"NO\n";
}
signed main(){
lmw;
cin>>a>>b>>p>>x0>>xx;
if(xx==x0){
cout<<"YES\n";
return 0;
}
if(a==0){
if(xx==b) cout<<"YES\n";
else cout<<"NO\n";
return 0;
}
if(a==1){
if(b==0){
cout<<"NO\n";
return 0;
}
}
int pp=(xx*a-xx+b)%p*power(x0*a-x0+b,p-2)%p;;
y=a;z=pp;
bsgs();
}