Số nguyên tố cũng có ứng dụng trong một số lĩnh vực của côngnghệ thông tin, chẳng hạn như mật mã hóa khóa công khai…Chính vì tầm quan trọng của sốnguyên tố nên ngay khi bắt đầu học về lậ
Trang 1M C L C ỤC LỤC ỤC LỤC
PHẦN I MỞ ĐẦU 1
I Lý do chọn đề tài 1
II Mục tiêu đề tài 1
1 Đối với giáo viên: 1
2 Đối với học sinh 1
III Phạm vi nghiên cứu 2
II.1 Ứng dụng định lý FERMAT nhỏ để kiểm tra số nguyên tố 2
II.2 Ứng dụng định lý FERMAT nhỏ để tính đồng dư 2
IV Phương pháp nghiên cứu 2
PHẦN II NỘI DUNG 3
I Ứng dụng định lý FERMAT nhỏ để kiểm tra số nguyên tố 3
I.1 Định lý FERMAT nhỏ 3
I.2 Ứng dụng định lý FERMAT nhỏ để kiểm tra số nguyên tố 3
2.3 Thuật toán Rabin-Miller 6
2.3.1 Ý tưởng 6
2.3.2 Phép thử xác suất (Probabilistic) 7
2.3.3 Thuật toán đơn định (Deterministic) 8
I.3 Một số ví dụ áp dụng 9
II Ứng dụng định lý FERMAT nhỏ để tính đồng dư 15
II.1 Một số tính chất của phép tính đồng dư 15
II.2 Khái niệm về nghịch đảo modulo của một số 15
II.3 Ứng dụng định lý FERMAT nhỏ tính đồng dư của một phân thức 16
II.4 Các ví dụ 18
PHẦN III KẾT LUẬN 24
TÀI LIỆU THAM KHẢO 25
Trang 2số và giải tích của các số Số nguyên tố cũng có ứng dụng trong một số lĩnh vực của côngnghệ thông tin, chẳng hạn như mật mã hóa khóa công khai…Chính vì tầm quan trọng của sốnguyên tố nên ngay khi bắt đầu học về lập trình, học sinh đã được làm quen với việc giảiquyết các bài toán liên quan đến số nguyên tố Trong các kỳ thi học sinh giỏi môn Tin học cáccấp từ trung học cơ sở trở lên có nhiều bài toán liên quan đến số nguyên tố.
Qua nhiều năm giảng dạy môn tin học cho học sinh từ Trung Học CS đến THPT, họcsinh chuyên cũng như không chuyên, qua theo dõi cũng như trực tiếp ra đề thi HSG các cấp,tôi nhận thấy có nhiều bài toán liên quan đến số nguyên tố như: Kiểm tra số nguyên tố, liệt kêcác số nguyên tố trên một đoạn, phân tích ra thừa số nguyên tố, thực hiện phép tính đồngdư(chia lấy dư) các phân thức có giá trị rất lớn Trong khi đó tài liệu nói về những vấn đề nàykhông đầy đủ, phân tán, chủ yếu là ở các trang mạng, vì vậy đôi khi còn sơ sài gây khó khăncho học sinh cũng như giáo viên Đa số học sinh mới chỉ biết thuật toán kiểm tra số nguyên tốtương đối nhỏ, liệt kê các số nguyên tố trên một đoạn liên tiếp không vượt quá 107 Về phéptính đồng dư của phân thức thì đa số không nắm được, trừ một số học sinh chuyên có thể nắmđược nhưng nhiều khi chỉ nhớ máy móc mà không hiểu bản chất
Tôi làm đề tài này với mong muốn có một tài liệu phục vụ việc giảng dạy của mình,đồng thời những thầy cô, học sinh nào thấy cần cũng có thể tham khảo Với khuôn khổ củamột sáng kiến kinh nghiệm nên không có tham vọng nhiều, tôi chỉ chọn trình bày hai vấn đềlà: Kiểm tra, liệt kê các số nguyên tố trong một đoạn với độ lớn các số đến 264 và tính đồng dưphân thức, với độ lớn tử và mẫu rất lớn Hai vấn đề này có liên quan rất nhiều đến định lýFermat nhỏ nên đề tài có tên là: MỘT SỐ ỨNG DỤNG ĐỊNH LÝ FERMAT NHỎ TRONGLẬP TRÌNH
Trong đề tài không tránh khỏi còn có những khiếm khuyết, rất mong nhận được sự góp
ý từ các bạn bè đồng nghiệp
II Mục tiêu đề tài.
1 Đối với giáo viên:
Phục vụ thi giáo viên giỏi
2 Đối với học sinh.
Giúp học sinh có một thuật toán hiệu quả để kiểm tra số nguyên tố lớntrong phạm vi biểu diễn số nguyên của ngôn ngữ lập trình
Trang 3 Giúp học sinh có thuật toán hiệu quả để tính đồng dư ( kết quả của phépchia lấy dư) của các phân thức nguyên (giá trị của phân thức sau khi rút gọn là nguyên)
có giá trị lớn vượt quá phạm vi biểu diễn số nguyên của ngôn ngữ lập trình
III Phạm vi nghiên cứu.
II.1 Ứng dụng định lý FERMAT nhỏ để kiểm tra số nguyên tố
2 Khái niệm về nghịch đảo modulo của một số
4 Các ví dụ
- Không gian: Đề tài được thực hiện tại trường THPT chuyên Lam Sơn.
- Thời gian thực hiện: 2023- 2024
IV Phương pháp nghiên cứu.
Kinh nghiệm bản thân, thảo luận, sưu tầm tài liệu, thử nghiệm thực tế,rút kinh nghiệm từ các tiết dạy trên lớp
khảo của các tác giả và tra cứu trên mạng internet với các đề thi Học sinh Giỏi rút ranhững kinh nghiệm, hệ thống lại kiến thức, mở ra các hướng mới
sinh giỏi để nắm tình hình trong việc giải các bài toán tin về số
tuyển HSG, các kỳ tập huấn, ra đề; qua tham khảo ý kiến đồng nghiệp, quý Thầy Cô
đã giảng dạy đội tuyển nhiều năm, từ đó rút ra được những vấn đề học sinh còn yếucần được bổ sung, những tài liệu nào giáo viên và học sinh đang cần
Phương pháp phân tích lý luận: Phân tích giúp học sinh nắm thật rõ bảnchất vấn đề, lựa chọn được phương pháp giải cho phù hợp
Trang 4PHẦN II NỘI DUNG
I Ứng dụng định lý FERMAT nhỏ để kiểm tra số nguyên tố
Định lý này còn có thể viết thu gọn như sau: Nếu a là một số nguyên dương
không chia hết cho p và p là một số nguyên tố thì a p-1 ≡ 1(mod p).
Định lý FERMAT nhỏ là một trường hợp riêng của định lý Euler phát biểu như
sau: Nếu n (n thuộc N * ) là số nguyên dương bất kỳ và a là số nguyên tố cùng nhau với
n, thì a φ (n) ≡ 1(mod n) Trong đó φ(n) là ký hiệu của phi hàm Euler đếm số các số nguyên giữa 1 và n nguyên tố cùng nhau với n
Định lý Euler là tổng quát hóa của định lý nhỏ Fermat vì nếu n = p là số nguyên
Ý tưởng: Nếu n > 1 và n không chia hết cho số nguyên nào
Ta có thể viết một hàm kiểm tra số nguyên n có phải là sốnguyên tố hay không như sau:
bool primeCheck(long long n)
Trang 5áp dụng hàm này với n ≤ 1014 Khi n lớn hơn hoặc khi phải kiểm tra tính nguyên tố củanhiều số nguyên dương thì thuật toán trên nhiều khi không đáp ứng được Ta có thể cảitiến thuật toán trên với tư tưởng: Nhận xét nếu số nguyên tố n lẻ thì n không chia hếtcho một số chẵn bất kì Do đó nếu n> 2, ta chỉ cần xét các số i lẻ thuộc đoạn [2, √n].
Tương tự, nếu n>3 thì ta chỉ cần xét i là các số không chia hết cho 3 Từ hai nhận xéttrên, nếu n>3 thì ta chỉ cần xét các số i sao cho i chia 6 dư 1 hoặc 5 xem có phải là ướccủa n hay không Thuật toán cải tiến cụ thể như sau:
bool primeCheck(int n)
tố, xóa bội của 3,… Thuật toán tiếp tục cho đến khi gặp số nguyên lớn hơn n thì dừng lại Tất cả các số chưa bị xóa là số nguyên tố
Ta có thể viết một đánh dấu các số nguyên tố trong đoạn [1, n]như sau:
Trang 6Độ phức tạp của thuật toán này là O(n√n¿, tuy nhiên trong thực
văn bản Mặc dù vậy khi kiểm tra tính nguyên tố của các số lớn hơn
2.2 Ứng dụng định lý FERMAT nhỏ để kiểm tra số nguyên tố
Trong phần này chúng ta sẽ nghiên cứu ứng dụng định lý Fermat nhỏ để kiểmtra số nguyên dương có phải là số nguyên tố hay không
Định lý Fermat nhỏ khẳng định: Nếu a là một số nguyên dương không chia hết
cho p và p là một số nguyên tố thì a p-1 ≡ 1(mod p).
Ngược lại, nếu an−1≡1(mod n) thì n có thể là số nguyên tố
Lưu ý: Ta chỉ chọn a∈[2, n−1] để đảm bảo a không chia hết cho p Mặt khác
nếu nếu an−1≢1(mod n) thì ta có ngay khẳng định n không phải là nguyên tố, tuy nhiênnếu an−1≡1(mod n) thì vẫn chưa thể khẳng định n là số nguyên tố Trong trường hợp
an−1≡1(mod n), để khẳng định n là nguyên tố hay không ta thử với nhiều giá trị a khácnhau, tuy nhiên cách làm này vẫn chưa hoàn toàn chính xác Ta cũng có thể dùng hàmkiểm tra số nguyên tố primeCheck(long long n) đã trình bày ở phần trên đểkhẳng định n nguyên tố hay không(trong trường hợp phải kiểm tra nhiều giá trị n), tuynhiên cách này chỉ áp dụng khi số lượng số cần kiểm tra không quá nhiều và độ lớncủa các số không quá lớn
Trang 7Hàm này có độ phức tạp là O(log k), trong tài liệu giáo khoa chuyên tin quyển 1
đã có trình bày bằng đệ quy, ở đây ta khử đệ quy Trong hàm này có phép toán a= a*a
%n nên chú ý chỉ chọn a≤109 để không tràn số
Bây giờ ta cài đặt hàm kiểm tra số n có là số nguyên tố hay không bằng phépthử Fermat:
bool isPrimefermat(long long n)
{
if (n < 7)
return n == 2 || n == 3 || n == 5;
const int repeatNum = 5;
for ( int i = 0; i < repeatNum; ++i)
Như đã nói ở trên, phép thử Fermat này không hoàn toàn chính xác, có những
số n có tính chất với mọi số nguyên a mà gcd(a,n)=1 thì an-1 % n vẫn bằng 1 nhưng số
đó lại không phải số nguyên tố, ví dụ n= 561 = 3.11.17 là số có tính chất như trên.Những số có tính chất như 561 người ta gọi là số Carmichael
Các số Carmichael phân bố rất ít trong tập các số tự nhiên Theo OEIS-A055553:
2.3 Thuật toán Rabin-Miller
2.3.1 Ý tưởng
Thuật toán Rabin-Miller là phiên bản mở rộng và mạnh hơn của phép thửFermat Thuật toán dựa vào nhận xét sau: Với mọi số nguyên dương x, tồn tại duy nhất hai số tự nhiên k,m sao cho x=2 k ×m và m lẻ.
Ví dụ: 6=21×3, 100=22×25, 9=20×9, 6=21×3,…
Trang 8Do đó, xét số n, ta có thể phân tích n−1 thành 2k×m, với m là số lẻ.
Theo định lý nhỏ Fermat, nếu n là số nguyên tố thì với mọi a sao cho gcd(a,n)
=1 ta có: an−1≡1(mod n) ⇔ a^(2k.m) −1≡ 0 (mod n) Vế trái có dạng A2 – B2, khai triển
vế trái ta được đẳng thức tương đương:
[a^(2k−1 m)+1].[a^(2k−2.m)+1]…(am+1)(am−1)≡0 (mod n)
Vì n là số nguyên tố nên tồn tại ít nhất một trong các nhân tử của vế trái chiahết cho n Do đó, thay vì kiểm tra kết luận của định lý Fermat nhỏ, ta sẽ kiểm tra điềukiện sau:
am≡1(mod n) hoặc
Tồn tại 0≤L≤k−1 sao cho a^(2L.m)≡−1(modn)
Nếu cả hai điều kiện không được thỏa mãn thì chắc chắn n là hợp số
Nhưng nếu một trong hai điều kiện được thỏa mãn thì n có phải số nguyên tốkhông?
Câu trả lời là không Ví dụ: với n=28, a=19 thì n−1=20×27 và 1927≡−1(mod 28)nhưng n= 28 không phải nguyên tố
Do đó, để áp dụng ý tưởng trên, ta có thể triển khai theo hai cách sau:
2.3.2 Phép thử xác suất (Probabilistic)
Để tăng tính chính xác của thuật toán ta có thể lặp lại bước kiểm tra với nhiều
cơ số a, giống như phép thử Fermat Hơn thế nữa, chứng minh được nếu n là hợp số,chỉ có ≈25% số cơ số a trong đoạn [2,n−1] thỏa mãn một trong hai điều kiện Nghĩa làvới hợp số n bất kì, xác suất để thuật toán chứng minh được n là hợp số sau lần kiểmtra đầu tiên là ≥75%, lần thứ hai là ≥93.75%, lần thứ ba là ≥98.43%, lần thứ x là (1−1/¿x))×100% Có thể thấy độ chính xác của thuật toán Rabin-Miller cao hơn nhiều sovới phép thử Fermat, và tất nhiên là đủ tốt cho các bài toán lập trình thi đấu
Cài đặt thuật toán:
Trang 9// Kiể m tra điể u kiện thuật toán với a cố định
bool test(long long a, long long n, long long k, long
const int repeatTime = 3;
for ( int i = 0; i < repeatTime; ++i)
Trang 102.3.3 Thuật toán đơn định (Deterministic)
Phép thử xác suất có thể trở thành thuật toán (đúng 100%) bằng cách thay vìxét a ngẫu nhiên, ta sẽ xét tất cả a bị chặn bởi một hàm theo n Bach chứng minh đượcchỉ cần xét a∈[2,2ln2n]
Với n đủ lớn thì vẫn có rất nhiều giá trị cần kiểm tra Hiện nay người ta cũng đãchứng minh được rằng:
for (auto a : checkSet)
if (a!=n &&!test(a, n, k, m)) // a!=n để, tránh trường hợp
Trang 113.1.1 Bài toán: Cho số nguyên dương n ≤ 4.106, hãy liệt kê các số nguyên tốtrong đoạn từ 1 đến n.
INPUT: Cho trong file NGUYENTO1.INP gồm duy nhất một số nguyên dươngn
OUTPUT: Ghi ra file NGUYENTO1.OUT các số tìm được trên một dòng theothứ tự tăng dần
3.1.2 Phân tích: Do đoạn cần liệt kê các số nguyên tố có khoảng cách lớn, các
số trong đoạn này lại không quá lớn, vì vậy ta sử dụng sàng nguyên tố là tốt hơn cả
Trang 123.2.1 Bài toán: Cho 2 số nguyên dương L ≤ R≤ 109, R-L≤ 5.103
, hãy liệt kêcác số nguyên tố trong đoạn từ L đến R
INPUT: Cho trong file NGUYENTO2.INP gồm 2 số nguyên dương L, R
OUTPUT: Ghi ra file NGUYENTO2.OUT các số tìm được trên một dòng theothứ tự tăng dần
3.2.2 Phân tích: Việc dùng sàng nguyên tố không còn khả thi do R có thể có
giá trị đến 109, do đó ta sẽ áp dụng thuật toán đơn định với phép thử MillerRabin
để giải quyết bài toán này
Trang 13bool test(long long a, long long n, long long k, longlong m)
{ long long mod = luythua(a, m, n);
Trang 14Trong chương trình này ta thấy:
vector<int> checkSet ={2,3,5,7}, lý do là L ≤ R≤ 109, như đã trình bày ở trên, tachỉ cần thử 4 giá trị của a là đủ
3.3 Ví dụ 3
3.3.1 Bài toán: Cho 2 số nguyên dương L ≤ R≤ 1018, R-L≤ 5.103
, hãy liệt kêcác số nguyên tố trong đoạn từ L đến R
INPUT: Cho trong file NGUYENTO3.INP gồm 2 số nguyên dương L, R
OUTPUT: Ghi ra file NGUYENTO3.OUT các số tìm được trên một dòng theothứ tự tăng dần
3.3.2 Phân tích: Việc dùng sàng nguyên tố không còn khả thi do R có thể có
giá trị đến 1018, do đó ta vẫn sẽ áp dụng thuật toán đơn định với phép thử MillerRabin để giải quyết bài toán này Tuy nhiên có một số vấn đề phải chỉnhsửa so với ví dụ 2 là:
vector<int> checkSet ={2,3,5,7,11,13,17,19,23,29,31,37}
Hàm luythua phải chỉnh sửa lại vì trong hàm này có phép toán a = (a * a)
% n, Như vậy trong quá trình lặp a có thể gần bằng 1018, khi đó lúc thực hiện phépnhân sẽ bị tràn số
Trang 15// Tính a * b mod n, sau này tính a*a mod n cho kho,i
long long binaryMul(long long a, long long b, longlong n)
bool test(long long a, long long n, long long k, longlong m)
{ long long mod = luythua2(a, m, n);
Trang 16Chương trình này chạy hết khoảng 0.5s trên máy bình thường khi cho R -L =
5000, R= 1018 Ta có thể dùng hàm này để tìm các số nguyên tố lớn trong một đoạn rấthiệu quả
Trang 17II Ứng dụng định lý FERMAT nhỏ để tính đồng dư
II.1 Một số tính chất của phép tính đồng dư
Đồng dư thức là phép toán lấy số dư của số này khi chia cho số khác, kí hiệu
là % Ví dụ: 5%2=1, khi đó có thể viết là 5≡1 (mod 2).
Phép đồng dư thức có tính chất phân phối đối với phép cộng, phép nhân và phéptrừ, cụ thể như sau:
(𝑎+𝑏)% 𝑐 =[(a %𝑐)+(b % 𝑐)] %c.
(𝑎-𝑏)% 𝑐 =[(a %𝑐)-(b % 𝑐)] %c.
(𝑎*𝑏)% 𝑐 =[(a %𝑐)*(b % 𝑐)] %c.
Riêng đối với phép chia, không có tính chất phân phối, mà phải sử dụng một lí
thuyết là Nghịch đảo modulo.
II.2 Khái niệm về nghịch đảo modulo của một số
Trong chương trình Toán phổ thông, người ta định nghĩa: Nghịch đảo của một
số nguyên 𝑎 (kí hiệu 𝑎−1 ) là số thỏa mãn: 𝑎.𝑎−1 =1.
Đối với nghịch đảo modulo, ta cũng có khái niệm tương tự, nhưng là xét trên
tập số dư khi chia cho 𝑀 Cụ thể ta có định nghĩa về nghịch đảo modulo như sau:
Định nghĩa: Nghịch đảo modulo 𝑀 của một số 𝑎 (cũng kí hiệu 𝑎−1 ) là số nguyên thỏa mãn: 𝑎.𝑎−1 ≡1(mod 𝑀)
Lưu ý: Nghịch đảo modulo M, chỉ xét trên tập số dư khi chia cho M Vì vậy khi
tìm a -1 nếu tìm được a -1 ≥M thì ta thay a -1 bằng a -1 %M, hai giá trị này coi là như nhau
là số chẵn nên chia cho 10 không thể dư 2
Như vậy không phải lúc nào cũng tồn tại 𝑎−1 Người ta đã chứng minh được chỉkhi 𝐺𝐶𝐷(𝑎,𝑀) =1 thì mới tồn tại 𝑎−l là nghịch đảo modulo 𝑀 của 𝑎, thật vậy:
Giả sử tồn tại a-1 của a theo modulo M 𝑎.𝑎−1 ≡1(mod 𝑀) 𝑎.𝑎−1 1≡0(mod 𝑀) 𝑎.𝑎−1 -1= k m với k nguyên (*) Cả 2 vế của (*) đều chia hết cho gcd(a,M) và 𝑎.𝑎−1 hiển nhiên cũng chia hết cho gcd(a,M), vậy 1 cũng phải chia hết cho gcd(a,M) Vậy (*) gcd(a,M) =1(Điều phải chứng minh)
-Để tính nghịch đảo modulo của một số, ta có thể sử dụng hai giải thuật: Giảithuật Euclid mở rộng hoặc dựa trên định lý Fermat nhỏ Phần tiếp theo ta sẽ xem xét
Trang 18ứng dụng định lý FERMAT nhỏ tính nghịch đảo modulo của một số và tính đồng dưcủa một phân thức.
II.3 Ứng dụng định lý FERMAT nhỏ tính đồng dư của một phân thức
3.1 Ứng dụng định lý FERMAT nhỏ tính nghịch đảo modulo của một số
Nhắc lại, định lý Fermat nhỏ khẳng định: Nếu a là một số nguyên dương không
chia hết cho M và M là một số nguyên tố thì a M-1 ≡ 1(mod M) Lưu ý với giả thiết của
3.2 Ứng dụng định lý FERMAT nhỏ tính đồng dư của một phân thức
3.2.1 Bài toán: Tính: a b%M, trong đó a b là số nguyên không âm và gcd(b,M)=1
3.2.2 Ý tưởng: Như đã nói ở trên, phép tính đồng dư không có tính chất phân
phối đối với phép chia, vì vậy bây giờ ta sẽ tìm cách đưa việc tính đồng dư của mộtphân thức về việc tính đồng dư của một tích:
Do a chia hết cho b, ta giả sử a = k.b (k nguyên), khi đó ta có: a b %M = k%M
Lưu ý: