【bzoj3122】: [Sdoi2013]随机数生成器 数论-BSGS
当a>=2 化简得
然后 BSGS 求解
其他的特判 :
当 x=t n=1
当 a=1
当 a=0 判断b==t
1 /* http://www.cnblogs.com/karl07/ */ 2 #include <cstdlib> 3 #include <cstdio> 4 #include <cstring> 5 #include <cmath> 6 #include <map> 7 #include <algorithm> 8 using namespace std; 9 10 #define LL long long 11 int T; 12 LL a,b,x,t,p; 13 14 LL Q_pow(LL x,LL y,LL p){ 15 LL ans=1; 16 while (y){ 17 if (y&1) ans=ans*x%p; 18 x=x*x%p; y=(y>>1); 19 } 20 return ans; 21 } 22 23 LL BSGS(LL a,LL b,LL p){ 24 if ((a==0 && b!=0) || (a==1 && b!=1)) return -2; 25 map<LL,LL> x; 26 LL sz=ceil(sqrt(p)),k=1,inv; 27 x.clear(); 28 x[1]=0; inv=Q_pow(Q_pow(a,sz,p),p-2,p); 29 for (int i=1;i<sz;i++){ 30 k=k*a%p; 31 if (!x.count(k)) x[k]=i; 32 } 33 for (int i=0;i<sz;i++){ 34 if (x.count(b)) return i*sz+x[b]; 35 b=b*inv%p; 36 } 37 return -2; 38 } 39 40 int main(){ 41 scanf("%d",&T); 42 for (int tt=1;tt<=T;tt++){ 43 scanf("%lld%lld%lld%lld%lld",&p,&a,&b,&x,&t); 44 if (x==t) { 45 puts("1"); 46 }else{ 47 if (a==0) { 48 printf("%d\n",b==t ? 2 : -1); 49 } 50 if (a==1) { 51 printf("%lld\n",b==0 ? -1 : (t-x+p)%p*Q_pow(b,p-2,p)%p+1); 52 } 53 if (a>=2){ 54 LL inv=Q_pow(a-1,p-2,p); 55 b=b*inv%p; 56 t=(t+b)%p; 57 x=(x+b)%p; 58 t=t*Q_pow(x,p-2,p)%p; 59 printf("%lld\n",BSGS(a,t,p)+1); 60 } 61 } 62 } 63 return 0; 64 }