【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 }
View Code

 

posted @ 2015-02-06 16:03  Tunix  阅读(236)  评论(0编辑  收藏  举报