这道题不难想,难的是分类讨论。
先是最一般的情况
推出公式套用bsgs。 这个要求答案>1且a!=1(等比数列的分类讨论)且a!=0(0没有逆元)
所以第一种情况a!=1 a!=0 ans=1
第二种情况 a!=1 a!=0 ans!=1
如果a=1,第一种情况ans=1
第二种情况 ans!=1 b=0 (0没有逆元)
第三种情况 ans!=1 b!=0
如果a=0,
a1=t 则ans=1
否则b=t ans=2
否则无解。
共8种情况。
#include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #define ll long long #define inf 1e9 #define eps 1e-10 #define md #define H 500000 #define N 100010 using namespace std; struct yts { int a,is,ne;}; struct ha { int v[H]; yts e[N]; int cnt; void clear() { memset(v,0,sizeof(v)); cnt=0; } void insert(ll a,int is) { int x=a%H,i; for (i=v[x];i;i=e[i].ne) if (e[i].a==a) break; if(!i) { i=++cnt; e[i].a=a; e[i].is=is; e[i].ne=v[x]; v[x]=i; } } int find(ll a) { int x=a%H,i; for (i=v[x];i;i=e[i].ne) if (e[i].a==a) break; if (i) return e[i].is; else return -1; } } hash; ll kpow(ll a,int b,int p) { ll ans=1; while (b) { if (b&1) ans=ans*a%p; a=a*a%p; b>>=1; } return ans; } void bsgs(ll a,ll b,int p) { //printf("bsgs %lld %lld %d\n",a,b,p); hash.clear(); int m=sqrt(a); ll ji=b,cheng=kpow(a,p-2,p); for (int i=0;i<m;i++) { hash.insert(ji,i); ji=ji*cheng%p; } ji=1; cheng=kpow(a,m,p); for (int i=0;i<p;i+=m) { int x=hash.find(ji); if (x!=-1) { printf("%d\n",x+i+1); return;} ji=ji*cheng%p; } printf("-1\n"); } int main() { #ifndef ONLINE_JUDGE freopen("data.in","r",stdin); freopen("data.out","w",stdout); #endif int tt; scanf("%d",&tt); while (tt--) { int p; ll a,b,x1,t; scanf("%d%lld%lld%lld%lld",&p,&a,&b,&x1,&t); if (a==0) { if (x1==t) printf("1\n"); else if (t==b) printf("2\n"); else printf("-1\n"); } else if (a==1) { if (t==x1) printf("1\n"); else { if (b==0) printf("-1\n"); else { ll x=(t-x1+b+p)%p; x=x*kpow(b,p-2,p)%p; if (x==0) printf("%d\n",p); else printf("%lld\n",x); } } } else { if (t==x1) printf("1\n"); else { ll x=((a-1)*t+b)%p,y=((a-1)*x1+b)%p; x=x*kpow(y,p-2,p)%p; bsgs(a,x,p); } } } }