Bài 65: Logarithm Rời Rạc (Baby-step Giant-step)¶
Tác giả: FPTOJ Team
Nội dung tham khảo từ: CP-Algorithms, VNOI Wiki
1. Bài Toán Logarithm Rời Rạc¶
1.1 Phát biểu¶
Cho \(a, b, p\) (với \(p\) nguyên tố). Tìm \(x\) sao cho:
Đây là bài toán logarithm rời rạc (discrete logarithm).
1.2 Ví dụ¶
\(2^x \equiv 8 \pmod{19}\) → \(x = 3\) vì \(2^3 = 8\).
\(3^x \equiv 13 \pmod{17}\) → \(x = 4\) vì \(3^4 = 81 = 4 \times 17 + 13\).
2. Thuật toán Baby-step Giant-step¶
2.1 Ý tưởng¶
Viết \(x = i \cdot m + j\) với \(m = \lceil \sqrt{p} \rceil\), \(0 \leq i, j < m\).
Bước 1 (Baby steps): Tính và lưu \(a^j \bmod p\) cho \(j = 0, 1, \ldots, m-1\) vào hash map.
Bước 2 (Giant steps): Với mỗi \(i = 0, 1, \ldots, m-1\), kiểm tra \(b \cdot (a^{-m})^i \bmod p\) có trong hash map không. Nếu có, \(x = im + j\).
2.2 Độ phức tạp¶
Thời gian: \(O(\sqrt{p} \log \sqrt{p})\) (do hash map).
Bộ nhớ: \(O(\sqrt{p})\).
2.3 Cài đặt¶
3. Trường hợp đặc biệt¶
3.1 \(b = 1\)¶
\(a^x \equiv 1 \pmod{p}\) → \(x\) là bội của bậc của \(a\) modulo \(p\). Luôn có nghiệm \(x = 0\) (hoặc \(x = \text{ord}(a)\)).
3.2 \(a = 0\)¶
\(0^x \equiv b \pmod{p}\): - \(x = 0\): \(0^0 = 1\) - \(x > 0\): \(0^x = 0\)
3.3 \(\gcd(a, p) > 1\)¶
Nếu \(p\) không nguyên tố, cần xử lý đặc biệt. Trong thi đấu, thường \(p\) là nguyên tố.
4. Ứng dụng¶
4.1 Tìm bậc của phần tử¶
Bậc của \(a\) modulo \(p\) (ký hiệu \(\text{ord}(a)\)) là số nguyên dương nhỏ nhất \(d\) sao cho \(a^d \equiv 1 \pmod{p}\).
\(\text{ord}(a)\) luôn là ước của \(\phi(p) = p - 1\) (với \(p\) nguyên tố).
Tìm bằng cách: phân tích \(p - 1\) thành thừa số, kiểm tra từng ước.
4.2 Giải phương trình mũ¶
\(a^x \equiv b \pmod{p}\) → dùng BSGS trực tiếp.
5. Mở rộng: \(p\) không nguyên tố¶
Khi \(p\) không nguyên tố, dùng Pollard's Rho để phân tích \(p\), rồi áp dụng Pohlig-Hellman algorithm. Tuy nhiên, trong thi đấu CP, thường chỉ cần BSGS với \(p\) nguyên tố.
6. Bài tập luyện tập¶
Bài 1: Discrete Logarithm cơ bản¶
Đề bài: Cho \(a, b, p\) (với \(p\) nguyên tố). Tìm số nguyên không âm \(x\) nhỏ nhất sao cho \(a^x \equiv b \pmod{p}\). Nếu không tồn tại, in -1.
Input: 3 số nguyên \(a, b, p\) \((2 \leq p \leq 10^9+7\), \(p\) nguyên tố, \(0 \leq a, b < p)\)
Output: Giá trị \(x\) hoặc -1.
Ví dụ:
| Input | Output |
|---|---|
2 8 19 |
3 |
3 13 17 |
4 |
2 7 13 |
11 |
Lời giải
Dùng Baby-step Giant-step. Viết \(x = im + j\) với \(m = \lceil\sqrt{p}\rceil\).
Bài 2: Tìm bậc của phần tử¶
Đề bài: Cho số nguyên tố \(p\) và số nguyên \(a\). Tìm bậc (order) của \(a\) modulo \(p\), tức số nguyên dương nhỏ nhất \(d\) sao cho \(a^d \equiv 1 \pmod{p}\).
Input: 2 số nguyên \(a, p\) \((2 \leq p \leq 10^9, 1 \leq a < p\), \(p\) nguyên tố\()\)
Output: Bậc của \(a\) modulo \(p\).
Ví dụ:
| Input | Output |
|---|---|
3 7 |
6 |
2 7 |
3 |
Giải thích (test 2): \(2^1=2, 2^2=4, 2^3=8\equiv 1 \pmod{7}\). Bậc = 3.
Lời giải
Phân tích \(p-1\), duyệt tất cả ước của \(p-1\), tìm ước nhỏ nhất \(d\) sao cho \(a^d \equiv 1\).
Bài 3: Giải phương trình mũ¶
Đề bài: Cho \(a, b, p\) (\(p\) nguyên tố). Tìm \(x\) nhỏ nhất sao cho \(a^x \equiv b \pmod{p}\).
Input: 3 số nguyên \(a, b, p\) \((2 \leq p \leq 10^6\), \(p\) nguyên tố\()\)
Output: \(x\) hoặc -1.
Ví dụ:
| Input | Output |
|---|---|
2 1 7 |
3 |
5 3 7 |
3 |
Giải thích (test 1): \(2^3 = 8 \equiv 1 \pmod{7}\).
Lời giải
BSGS hoặc brute force nếu \(p\) nhỏ.