[SDOI2011]計算器

傳送機

1、計算$y^x mod\ p$ 的值;

2、計算滿足$x \times y \equiv z(mod\ p)$的最小非負整數$x$;

3、計算滿足$y^x \equiv z(mod\ p)$的最小非負整數$x$。

 

BSGS , 拓歐 , 快速冪模板題

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cmath>
 5 #include <map>
 6 #define inc(i) (++ (i))
 7 #define dec(i) (-- (i))
 8 using namespace std;
 9 
10 int Q , k , A , B , P , x , y , d;
11 
12 inline int KSM(int x , int p)
13 {
14     int Ans = 1;
15     while(p)
16     {
17         if(p & 1) Ans = 1ll * Ans * x % P;
18         x = 1ll * x * x % P , p >>= 1;
19     }
20     return Ans;
21 }
22 
23 inline void Exgcd(int a , int b , int& x , int& y , int& d)
24 {
25     if(b == 0)
26     {
27         x = 1 , y = 0 , d = a;
28         return;
29     }
30     Exgcd(b , a % b , y , x , d);
31     y -= a / b * x;
32 }
33 
34 #define int long long
35 map <int  , int> M;
36 inline int BSGS(int A , int B , int C)
37 {
38     if(A % P == 0 && B != 0) return -1;
39     if(A % P == 0 && B == 0) return 1;
40     M.clear();
41     int m = (int)ceil(sqrt(1.0 * C)) , Now;
42     Now = B % C , M[Now] = 0;
43     for(int i = 1 ; i <= m ; inc(i))
44         Now = Now * A % C , M[Now] = i;
45     A = KSM(A , m) , Now = 1;
46     for(int i = 1 ; i <= m ; inc(i))
47     {
48         Now = Now * A % C;
49         if(M[Now]) return i * m - M[Now];
50     }
51     return -1;
52 }
53 #undef int
54 
55 int main()
56 {
57     scanf("%d%d" , &Q , &k);
58     if(k == 1)
59         while(Q --)
60         {
61             scanf("%d%d%d" , &A , &B , &P);
62             printf("%d\n" , KSM(A , B));
63         }
64     else
65         if(k == 2)
66             while(Q --)
67             {
68                 scanf("%d%d%d" , &A , &B , &P);
69                 Exgcd(A , P , x , y , d);
70                 if(B % d)
71                 {
72                     puts("Orz, I cannot find x!");
73                     continue;
74                 }
75                 while(x < 0) x += P;
76                 x %= P;
77                 printf("%d\n" , (1ll * x * B / d) % P);
78             }
79         else
80             while(Q --)
81             {
82                 scanf("%d%d%d" , &A , &B , &P);
83                 long long Ans = BSGS(1ll * A , 1ll * B , 1ll * P);
84                 if(~Ans) printf("%lld\n" , Ans);
85                 else puts("Orz, I cannot find x!");
86             }
87     return 0;
88 }
SDOI2011

 

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章