The main difficulty of this question is how to solve the third question.
So we need to know what kind of a way bsgs is.
First bsgs is a kind of meet in the middle (poke below)
http://m.blog.csdn.net/blog/zentropy/11200099
Read the link and see the following:
--------------------------------------------------------------------------------------------------------------- ------
For a prime number p we know by the Fermat theorem that y^xmodp up to (p-1) times is a cyclic section
So if there's a solution, x must be 0 to p-1.
So we just need to know if X takes 0 to p-1 if there's a solution.
According to the thought of meet in the middle M=sqrt (p-1)
Then we just need to find out 0~m-1 (if there is a solution to exit here)
And then find out m,2m,3m......nm (nm<=p-1)
Ask y^ (0~m-1) If there are and y^km multiply MODP equals Z.
It is clear, however, that this operation is done directly by sqrt (n) *sqrt (n) =n
So I learned how to find the inverse of the y^km and then we can multiply the inverse of the modp meaning with Z
Then ask y^ (0~m-1) If there is no equal to it
Doing this is sqrt (n) the complexity of *hash
With the manual hashing technique, the hash complexity can be considered as 1.
More lazy words directly with map to hash is log (n)
#include <bits/stdc++.h>using namespaceStd;map<int,int>MP;intSolve1 (intXintYintMoD) { Long LongT=x,re=1; while(y) {if(y&1) Re=re*t%MoD; T=t*t%MoD; Y>>=1; } return(int) re;}intEXGCD (intAintBint&x,int&y) { if(!b) {x=1; Y=0; returnA; } intt,d; D=EXGCD (b,a%b,x,y); T=x; X=y; Y=t-(A/b) *x; returnD; }voidSolve2 (intYintZintp) { intX,yy; intD=EXGCD (Y,P,X,YY); if(z%d) {puts ("Orz, I cannot find x!"); return; } x=(Long Long) x* (z/d)%p; X= (x<0? x+p:x); printf ("%d\n", x);}BOOLSolve3 (intYintZintp) {//if (z>=p)//return 0;y%=p; if(!y) {if(z)return 0; Puts ("1"); return 1; } mp.clear (); intM=ceil (sqrt (P-1)); Long Longt=1; for(intI=0; i<m;++i) {if(t==z) {printf ("%d\n", i); return 1; } if(!mp[t]) mp[t]=i+1; Else return 0; T=t*y%p; } intInv=solve1 (y,p-1-m,p); T=Z; for(inti=m;i<=p-2; i+=m) {T=t*inv%p; if(Mp[t]) {printf ("%d\n", i+mp[t]-1); return 1; } } return 0;}intMain () {intt,ca,y,z,p; scanf ("%d%d",&t,&CA); while(t--) {scanf ("%d%d%d",&y,&z,&p); if(ca==1) printf ("%d\n", Solve1 (y,z,p)); Else if(ca==2) solve2 (y,z,p); Else if(ca==3) if(!Solve3 (y,z,p)) puts ("Orz, I cannot find x!"); } return 0;}
Bzoj 2242: [SDOI2011] Calculator & BSGS Algorithm notes