1 #include<cstdio>
  2 #include<iostream>
  3 #include<map>
  4 #include<cmath>
  5 #define ll long long
  6 using namespace std;
  7 ll T,p,a,b,c,x1,t;
  8 map<ll,ll> mp;
  9 ll exgcd(ll b,ll p,ll &x,ll &y)
 10 {
 11     if(!p)
 12       {
 13         x=1;
 14         y=0;
 15         return b;
 16       }
 17     ll t1=exgcd(p,b%p,x,y);
 18     ll t=x;
 19     x=y;
 20     y=t-b/p*y;
 21     return t1;
 22 }
 23 ll kuai(ll a,ll k,ll p)
 24 {
 25     ll ans=1;
 26     for(;k;)
 27       {
 28         if(k%2)
 29           ans=(ans*a)%p;
 30         k/=2;
 31         a=(a*a)%p;
 32       }
 33     return ans;
 34 }
 35 ll pan(ll y,ll z,ll p)
 36 {
 37     mp.clear();
 38     ll m=ceil(sqrt(p)),t=1;
 39     mp[1]=m+1;
 40     for(ll i=1;i<m;i++)
 41         {
 42            t=t*y%p;
 43            mp[t]=i;
 44         }
 45     ll T=kuai(y,p-m-1,p),ine=1;
 46     for(ll k=0;k<=m;k++)
 47        {
 48            ll i=mp[z*ine%p];
 49            if(i)
 50               {
 51                 if(i==m+1)
 52                   i=0;
 53                 return k*m+i+1;
 54               } 
 55           ine=ine*T%p;
 56        }
 57     return -1;
 58 }
 59 ll solve()
 60 {
 61     if(x1==t) 
 62       return 1;
 63     if(a==0)
 64       {
 65         if(b==t)
 66           return 2;
 67         return -1;
 68       }
 69     if(a==1)
 70       {
 71         c=(t-x1+p)%p;
 72         ll x,y;
 73         ll t1=exgcd(b,p,x,y);
 74         if(c%t1)
 75           return -1;
 76         c/=t1;
 77         x=x*c%p;
 78         for(;x<0;x+=p);
 79         return x+1;
 80       }
 81     if(a>1)
 82       {
 83         c=kuai(a-1,p-2,p);
 84         ll x,y,d=(b*c+t)%p;
 85         ll t1=exgcd((x1+b*c)%p,p,x,y);
 86         if(d%t1)
 87           return -1;
 88         d/=t1;
 89         x=x*d%p;
 90         for(;x<0;x+=p);
 91         a%=p;
 92         x%=p;
 93         if(!a&&!x)
 94           return 2;
 95         if(!a)
 96           return -1;
 97         return pan(a,x,p);
 98       }
 99 }
100 int main()
101 {
102     scanf("%lld",&T);
103     for(int i=1;i<=T;i++)
104       {
105         scanf("%lld%lld%lld%lld%lld",&p,&a,&b,&x1,&t);
106         printf("%lld\n",solve());
107       }
108     return 0;
109 }

当 a==0时,判断b,当a==1时,exgcd否则BSGS

posted on 2016-03-22 23:12  xiyuedong  阅读(187)  评论(0编辑  收藏  举报