A whole bunch of borders was not known at first, and after a few random sentences, WA
Helpless to download the data, and then crazy to judge all kinds of strange boundaries
To gouge out the boundary problem
First we consider the situation of a=1
X1+k*b=t (mod p)
EX_GCD can be solved
Consider the situation of a>1
Make s=x+b/(A-1)
The original is becoming a geometric series.
S1*a^k= (t+b/(A-1)) (mod p)
BSGS solution after moving the item
All other boundaries can be judged by O (1)
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include < cstdlib> #include <map> #include <cmath>using namespace std; typedef long Long Ll;int T; ll P,a,b,x1,x,y,d,t,inv;map<ll,int>q;void EX_GCD (ll a,ll b,ll &d,ll &x,ll &y) {if (b==0) {x=1;y=0;d=a; return;} EX_GCD (b,a%b,d,y,x); y-= (A/b) *x;} ll Pow_mod (ll V,ll b) {ll tmp=1; while (b) {if (b&1) tmp=tmp*v%p; v=v*v%p;b>>=1; }return tmp;} ll Log_mod (ll a,ll b,ll N) {if (a==0&&b==0) return 1; if (a==0) return-1; LL m= (int) (sqrt (n+0.5)) +1; Q.clear (); LL V=pow_mod (a,m); V=pow_mod (v,n-2); LL e=1; q[1]=0; for (int i=1;i<m;++i) {e=e*a%n; if (! Q.count (e)) q[e]=i; } for (int i=0;i<m;++i) {if (Q.count (b)) return i*m+q[b]+1; b=b*v%n; }return-1;} int main () {scanf ("%d", &t); while (t--) {scanf ("%lld%lld%lld%lld%lld", &p,&a,&b,&x1,&t); if (x1==t) {PrinTF ("1\n"); continue;} if (a==0) {if (b==t) {printf ("2\n"); continue;} else {printf (" -1\n"); continue;} } if (a==1) {if (b==0) {printf (" -1\n"); continue;} EX_GCD (B,p,d,x,y); x1= (t-x1+p)%p; if (x1%d!=0) {printf (" -1\n"); continue;} x=x*x1; x= (x%p+p)%p; printf ("%lld\n", x+1); Continue } inv=pow_mod (A-1,p-2); b=b*inv%p; x1= (x1+b)%p;t= (t+b)%p; X1=pow_mod (x1,p-2); t=t*x1%p; printf ("%lld\n", Log_mod (a,t,p)); }return 0;}
Bzoj 3122 SDOI2013 Random number generator