评论

收藏

[C++] 【BZOJ】【3239】Discrete Logging

编程语言 编程语言 发布于:2021-08-04 15:27 | 阅读数:398 | 评论:0

BSGSBSGS裸题,嗯题目中也有提示:求a^m (mod p)的逆元可用快速幂,即 pow(a,P-m-1,P) * (a^m) = 1 (mod p)
DSC0000.gif DSC0001.gif
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



关注下面的标签,发现更多相似文章