[SDOI2013]随机数生成器

传送机

$X_{i +1} \equiv a \times x_i + b(mod p)$

求最小的$n$,使得$x_n=t$

枚举找通项可得 $X_n=a^{n - 1}\times X_1+b\times \dfrac{a^{n - 1} - 1}{a - 1}$

设$c$为$a - 1$的逆元则有答案$n$ , $(x_1+b \times c) \times a^{n-1} \equiv b \times c + t (mod\ p)$

则有$a^{n-1} \equiv (b \times c + t) * (x_1 + b \times c)^{-1} (mod\ p)$

$BSGS$即可

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

猜你喜欢

转载自www.cnblogs.com/Shine-Sky/p/9651136.html