【BZOJ】【3239】Discrete Logging
BSGS
BSGS裸题,嗯题目中也有提示:求a^m (mod p)的逆元可用快速幂,即 pow(a,P-m-1,P) * (a^m) = 1 (mod p)
1 /************************************************************** 2 Problem: 3239 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:208 ms 7 Memory:2872 kb 8 ****************************************************************/ 9 10 //BZOJ 3239 11 #include<cmath> 12 #include<map> 13 #include<cstdio> 14 #include<cstring> 15 #include<cstdlib> 16 #include<iostream> 17 #include<algorithm> 18 #define rep(i,n) for(int i=0;i<n;++i) 19 #define F(i,j,n) for(int i=j;i<=n;++i) 20 #define D(i,j,n) for(int i=j;i>=n;--i) 21 using namespace std; 22 int getint(){ 23 int v=0,sign=1; char ch=getchar(); 24 while(!isdigit(ch)) {if(ch=='-') sign=-1; ch=getchar();} 25 while(isdigit(ch)) {v=v*10+ch-'0'; ch=getchar();} 26 return v*sign; 27 } 28 /*******************template********************/ 29 typedef long long LL; 30 LL pow(LL a,LL b,LL P){ 31 LL r=1,base=a%P; 32 while(b){ 33 if (b&1) r=r*base%P; 34 base=base*base%P; 35 b>>=1; 36 } 37 return r; 38 } 39 LL log_mod(LL a,LL b,LL P){ 40 LL m,v,e=1; 41 m=ceil(sqrt(P+0.5)); 42 v=pow(a,P-m-1,P); 43 map<LL,LL>x; 44 x[1]=0; 45 for(int i=1;i<m;++i){ 46 e=e*a%P; 47 if(!x.count(e)) x[e]=i; 48 } 49 rep(i,m){ 50 if (x.count(b)) return (LL) i*m+x[b]; 51 b=b*v%P; 52 } 53 return -1; 54 } 55 int main(){ 56 LL P,b,n; 57 while(scanf("%lld%lld%lld",&P,&b,&n)!=EOF){ 58 b%=P; n%=P; 59 if (!b && !n) {printf("1\n"); continue;} 60 if (!b) {printf("no solution\n"); continue;} 61 LL ans=log_mod(b,n,P); 62 if (ans==-1){printf("no solution\n");continue;} 63 printf("%lld\n",ans); 64 } 65 return 0; 66 }