洛谷P3306 [SDOI2013]随机数生成器(BSGS)
感觉我BSGS都白学了……数学渣渣好像没有一道数学题能自己想出来……
要求$X_{i+1}=aX_i+b\ (mod \ \ p)$
左右同时加上$\frac{b}{a-1}$,把它变成等比数列$$X_{i+1}+\frac{b}{a-1}=a(X_i+\frac{b}{a-1}) \ (mod\ p)$$
然后根据等比数列递推公式$$X_n+\frac{b}{a-1}=a^{n-1}(X_1+\frac{b}{a-1}) \ (mod\ p)$$
那么我们要求$n$,已知$$a^{n-1}≡(X_n+b*inv(a-1))*inv(X_1+b*inv(a-1))\ (mod\ p)$$
然后除了$n$都已知,那么就是一个BSGS了
1 //minamoto 2 #include<iostream> 3 #include<cstdio> 4 #include<cmath> 5 #include<map> 6 #define ll long long 7 using namespace std; 8 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 9 char buf[1<<21],*p1=buf,*p2=buf; 10 inline ll read(){ 11 #define num ch-'0' 12 char ch;bool flag=0;ll res; 13 while(!isdigit(ch=getc())) 14 (ch=='-')&&(flag=true); 15 for(res=num;isdigit(ch=getc());res=res*10+num); 16 (flag)&&(res=-res); 17 #undef num 18 return res; 19 } 20 map<ll,ll> mp; 21 ll p,a,b,x1,xn; 22 inline ll ksm(ll a,ll b){ 23 ll res=1;a%=p; 24 while(b){ 25 if(b&1) (res*=a)%=p; 26 (a*=a)%=p,b>>=1; 27 } 28 return res; 29 } 30 ll BSGS(ll a,ll b,ll p){ 31 if(a%p==0) return -1;mp.clear(); 32 ll t=sqrt(p)+1,at=ksm(a,t); 33 for(int j=0;j<=t;++j){mp[b]=j,b=b*a%p;} 34 ll mul=1; 35 for(int i=1;i<=t;++i){ 36 mul=mul*at%p; 37 if(mp[mul]) return i*t-mp[mul]+1; 38 } 39 return -1; 40 } 41 int main(){ 42 // freopen("testdata.in","r",stdin); 43 int T=read(); 44 while(T--){ 45 p=read(),a=read(),b=read(),x1=read(),xn=read(); 46 if(x1==xn){puts("1");continue;} 47 if(a==0){puts(xn==b?"2":"-1");continue;} 48 if(a==1&&b==0){puts("-1");continue;} 49 if(a==1){ 50 ll ny=ksm(b,p-2); 51 ll ans=((((xn-x1)%p+p)%p)*ny%p)%p; 52 printf("%lld\n",ans+1);continue; 53 } 54 ll inv=b%p*ksm(a-1,p-2)%p,s=(xn%p+inv)%p; 55 ll t=ksm((x1%p+inv)%p,p-2)%p; 56 ll ans=BSGS(a,s*t%p,p); 57 printf("%lld\n",ans); 58 } 59 return 0; 60 }
深深地明白自己的弱小