1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
| #include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
typedef long long Int64;
struct Triple
{
Int64 x, y, z;
Triple(const Int64 a, const Int64 b, const Int64 c): x(a), y(b), z(c) { }
};
Triple exgcd(const Int64 a, const Int64 b)
{
if (!b) return Triple(1, 0, a);
const Triple last = exgcd(b, a%b);
return Triple(last.y, last.x - a / b * last.y, last.z);
}
class Hash
{
static const int HASHMOD = 7679977;
Int64 k[HASHMOD+100];
int time[HASHMOD+100], v[HASHMOD+100], timestamp;
int locate(const Int64 key)
{
int h = key%HASHMOD;
while (time[h] == timestamp && k[h] != key) ++h;
return h;
}
public:
void clear() { ++timestamp; }
void set(const Int64 key, const int value)
{
const int h = locate(key);
if (time[h] != timestamp) time[h] = timestamp, k[h] = key, v[h] = value;
}
int get(const Int64 key)
{
const int h = locate(key);
return time[h] == timestamp ? v[h] : -1;
}
} hash;
int bsgs(Int64 A, Int64 B, Int64 C)
{
hash.clear();
Int64 base = 1, D = 1;
const int m = static_cast<int>(std::ceil(std::sqrt(C)));
for (int i = 0; i < m; ++i, base = base*A%C) hash.set(base, i);
for (int i = 0; i <= m; ++i)
{
Triple gcd = exgcd(D, C);
const int j = hash.get((gcd.x*B%C+C)%C);
if (j != -1) return i*m+j;
D = D*base%C;
}
return -1;
}
Int64 T, p, a, b, x1, t;
int solve()
{
scanf("%lld%lld%lld%lld%lld", &p, &a, &b, &x1, &t);
if (x1 == t) return 1;
if (a == 0) return b == t ? 2 : -1;
if (a == 1)
{
Triple gcd = exgcd(b, p);
if (std::abs(gcd.z) != 1) return -1;
return ((t-x1)/gcd.z*gcd.x%p+p)%p+1;
}
const Int64 tmp1 = (1-a)*x1-b;
const Triple gcd = exgcd(tmp1, p);
if (std::abs(gcd.z) != 1) return -1;
const Int64 tmp2 = (t-t*a-b) % p * gcd.x / gcd.z % p;
const int res = bsgs(a, (tmp2+p)%p, p)+1;
return res < 1 ? -1 : res;
}
int main()
{
scanf("%lld", &T);
while (T--)
printf("%d\n", solve());
}
|