- vừa được xem lúc

Đồng dư (phần 1)

0 0 20

Người đăng: Viblo Algorithm

Theo Viblo Asia

Giới thiệu

Các kiến thức liên quan tới số học luôn đóng vai trò quan trọng trong lập trình thi đấu. Chúng có ứng dụng thực tiễn liên quan đến đời sống, đồng thời cũng đưa cho ta những quan sát, nhận xét quan trọng khi tiếp cận một vấn đề trong lập trình. Đôi khi, những quan sát này chính là "key" để giải một bài toán hóc búa, hay đơn giản giúp bạn có thêm ý tưởng để cải thiện độ phức tạp của chương trình. Nếu không nắm vững các lý thuyết liên quan đến số học, bạn dễ bị mắc phải những sai sót liên quan đến tính chất trong các phép toán. Trong series về lý thuyết số học, Viblo sẽ trình bày các chuyên đề quan trọng giúp bạn tự tin hiểu và xử lý các bài lập trình thi đấu nặng về tính toán học. Ở bài viết đầu tiên, Viblo sẽ giới thiệu tới các bạn về đồng dư, một khái niệm thường xuyên gặp phải trong lập trình thi đấu. Bài viết được tham khảo từ sách Lý thuyết sơ cấp của các số - W. SIERPINSKI

Đồng dư và các tính chất

Giả sử aabb là các số nguyên. Ta nói rằng aa đồng dư với bb theo modulo mm nếu hiệu của aabb chia hết cho mm. Sử dụng ký hiệu được đề xuất bởi Gauss ta viết:

ab(modm)a \equiv b ( \bmod m ) (1)

Công thức (1) tương đương với mabm | a - b

Rõ ràng nếu hai số nguyên là đồng dư modulo mm thì chúng có cùng số dư khi chia cho mm. Ký hiệu đồng dư \equiv được sử dụng khá giống ký hiệu ==. Ta liệt kê dưới đây một số mối liên hệ giữa các đồng dư thức và các đẳng thức.

Tính phản xạ: Mọi số nguyên là đồng dư với chính nó theo mọi modulo, nghĩa là aa(modm)a \equiv a (\bmod m) với mọi số nguyên a và mọi số tự nhiên mm vì rõ ràng aa=0a-a = 0 chia hết cho mọi số tự nhiên mm.

Tính đối xứng: Đồng dư thức (1) tương đương với đồng dư thức ba(modm)b \equiv a (\bmod m ) vì rõ ràng các số aba – bbab – a cùng chia hết hoặc cùng không chia hết cho mm.

Tính kết hợp: nếu ab(modm)a \equiv b (\bmod m)bc(modm)b \equiv c (\bmod m ) thì ac(modm)a \equiv c (\bmod m ) vì ta có đẳng thức ac=(ab)+(bc)a-c = (a-b) + (b-c) và lưu ý tổng của hai số chia hết cho mm là một số chia hết cho mm.

Ta có một số tính chất khác của đồng dư sau đây. Ta chứng minh hai đồng dư thức với cùng modulo có thể cộng hoặc trừ tương ứng các vế. Thật vậy giả sử

ab(modm) vaˋ cd(modm)a \equiv b ( \bmod m ) \text { và } c \equiv d ( \bmod m ) (2)

Để chứng minh a+cb+d(modm)a+c \equiv b+d(\bmod m)acbd(modm)a-c \equiv b-d(\bmod m) ta lưu ý các đẳng thức (a+c)(b+d)=(ab)+(cd)(a+c)-(b+d)=(a-b)+(c-d)(ac)(bd)=(ab)(cd)(a-c)-(b-d)=(a-b)-(c-d). Tương tự sử dụng đẳng thức acbd=(ab)c+(cd)ba c-b d=(a-b) c+(c-d) b, ta chứng minh được từ (2) suy ra đồng dư thức acbd(modm)a c \equiv b d(\bmod m). Hệ quả là ta có thể nhân theo vế hai đồng dư thức với cùng modulo.

Các định lý về các tính chất cộng, trừ, nhân các đồng dư thức ở trên có thể mở rộng cho hữu hạn các đồng dư thức.

Định lý về phép cộng các đồng dư thức chứng tỏ ta có thể chuyển vế đối dấu mọi hạng tử trong một đồng dư thức bởi vì phép toán này tương đương với việc trừ các hạng tử trong cả hai vế.

Từ tính chất phép nhân các đồng dư thức chứng tỏ có thể nhân một đồng dư thức với mọi só nguyên tùy ý và do đó ta có thể lũy thừa cả hai vế của đồng dư thức với số mũ bất kỳ.

Tuy nhiên ta không thể chia một đồng dư thức cho một đồng dư thức khác (ngay cả khi thương số là các số nguyên). Chẳng hạn 4818(mod10)48 \equiv 18(\bmod 10)122(mod10)12 \equiv 2(\bmod 10) nhưng không có 49(mod10)4 \equiv 9(\bmod 10).

Do một ước số của ước số của một số nguyên cũng là ước số của số nguyên đó nên nếu dmd \mid m thì đồng dư thức ab(modm)a \equiv b(\bmod m) chứng tỏ ab(modd)a \equiv b(\bmod d).

Tính kết hợp của các đồng dư thức cùng với tính chất cộng và nhân các đồng dư thức chứng tỏ trong đồng dư thức cho trước ta có thể thay mọi hạng tử hoặc nhân tử bởi các số đồng dư với nó.

Quy tắc này không đúng với các lũy thừa. Chẳng hạn đồng thức thức 264(mod5)2^{6} \equiv 4(\bmod 5) không thể thay thế bởi đồng dư thức 214(mod5)2^{1} \equiv 4(\bmod 5) mặc dù 61(mod5)6 \equiv 1(\bmod 5).

Giả sử f(x)=A0xn+A1xn1++An1+Anf(x)=A_{0} x^{n}+A_{1} x^{n-1}+\ldots+A_{n-1}+A_{n} là đa thức bậc nn với hệ số nguyên. Ký hiệu mm là số tự nhiên và a,ba, b là các số nguyên thỏa mãn ab(modm)a \equiv b(\bmod \mathrm{m}). Từ định lý về các lũy thừa tự nhiên và tính chất nhân các đồng dư thức suy ra

A0anA0bn(modm),A1an1A1bn1(modm),An1aAn1b(modm),AnAn(modm).\begin{aligned} &A_{0} a^{n} \equiv A_{0} b^{n}(\bmod m), \\ &A_{1} a^{n-1} \equiv A_{1} b^{n-1}(\bmod m), \\ &\cdots \\ &A_{n-1} a \equiv A_{n-1} b(\bmod m), \\ &A_{n} \equiv A_{n}(\bmod m) . \end{aligned}

Cộng lại ta có A0an+A1an1++An1a+AnA0bn+A1bn1++An1b+An(modm)A_{0} a^{n}+A_{1} a^{n-1}+\ldots+A_{n-1} a+A_{n} \equiv A_{0} b^{n}+A_{1} b^{n-1}+\ldots+A_{n-1} b+A_{n}(\bmod m). Nghĩa là f(a)f(b)(modm)f(a) \equiv f(b)(\bmod m). Ta đã chứng minh được

Định lý 1. Nếu f(x)f(x) là đa thức một biến xx với hệ số nguyên thì đồng dư thức ab(modm)a \equiv b(\bmod \mathrm{m}) suy ra đồng dư thức f(a)f(b)(modm)f(a) \equiv f(b)(\bmod m).

Định lý 1 cho ta quy tắc cho biết một số có chia hết cho 9,7,11,13,27,37 hay không.

Ký hiệu NN là số tự nhiên. Biểu diễn của NN trong hệ thập phân được cho bởi biểu diễn có dạng N=c110n1+c210n2++cn110+cnN=c_{1} 10^{n-1}+c_{2} 10^{n-2}+\ldots+c_{n-1} 10+c_{n}. Đặt (3)

f(x)=c1xn1+c2xn2++cn1x+cnf(x)=c_{1} x^{n-1}+c_{2} x^{n-2}+\ldots+c_{n-1} x+c_{n}

Khi đó f(x)f(x) là đa thức hệ số nguyên và (4)

f(10)=Nf(10)=N

Theo Định lý 1 thì vì 101(mod9)10 \equiv 1(\bmod 9) ta có (5)

f(10)f(1)(mod9)f(10) \equiv f(1)(\bmod 9)

Nhưng f(1)=c1+c2++cnf(1)=c_{1}+c_{2}+\ldots+c_{n} và hệ quả là theo (4)(4)(5)(5) thì Nc1+c2++cn(mod9)N \equiv c_{1}+c_{2}+\ldots+c_{n}(\bmod 9) chứng tỏ mọi số tự nhiên NN sai khác tổng các chữ số của nó trong hệ cơ số 10 một bội số của 9. Do đó NN chia hết cho 9 khi và chỉ khi tổng các chữ số của nó chia hết cho 9. Tổng quát hơn nếu ký hiệu SNS_{N} là tổng các chữ số của NN (trong hệ thập phân) thì với các số tự nhiên NNNN^{\prime} ta có NsN(mod9)N \equiv s_{N}(\bmod 9), NsN(mod9)N^{\prime} \equiv s_{N^{\prime}}(\bmod 9) suy ra NNsNsN(mod9)N N^{\prime} \equiv s_{N} s_{N^{\prime}}(\bmod 9). Vì NNsN(mod9)N N^{\prime} \equiv s_{N^{\prime}}(\bmod 9) nên sNNsNsN(mod9)s_{N N^{\prime}} \equiv s_{N^{\prime}} s_{N^{\prime}}(\bmod 9).

Từ (3) và đồng dư thức 101(mod11)10 \equiv-1(\bmod 11), Định lý 1 suy ra f(10)f(1)(mod11)f(10) \equiv f(-1)(\bmod 11), do đó theo (4) và (3) ta có (1)n1Nc1c2+c3c4+(mod11)(-1)^{n-1} N \equiv c_{1}-c_{2}+c_{3}-c_{4}+\ldots(\operatorname{mod11}). Từ đây ta nhận được quy tắc về tính chia hết cho 11. Bây giờ ta tìm các quy tắc về tính chia hết cho 7 hoặc 13.13 .

Ký hiệu (c1,c2,,cn)10\left(c_{1}, c_{2}, \ldots, c_{n}\right)_{10} là số trong hệ thập phân có các chữ số là c1,c2,,cnc_{1}, c_{2}, \ldots, c_{n} (ký hiệu này là cần thiết để phân biệt với tích các chữ số c1,c2,,cnc_{1}, c_{2}, \ldots, c_{n} ). Mọi số tự nhiên đều có dạng N=(cn2cn1cn)10+(cn5cn4cn3)101000+(cn8cn7cn6)1010002+N=\left(c_{n-2} c_{n-1} c_{n}\right)_{10}+\left(c_{n-5} c_{n-4} c_{n-3}\right)_{10} \cdot 1000+\left(c_{n-8} c_{n-7} c_{n-6}\right)_{10} \cdot 1000^{2}+\ldots10001(mod7)1000 \equiv-1(\bmod 7)10001(mod13)1000 \equiv-1(\bmod 13) nên ta có N(cn2cn1cn)10(cn5cn6cn7)10+(cn8cn7cn6)10(mod7)N \equiv\left(c_{n-2} c_{n-1} c_{n}\right)_{10}-\left(c_{n-5} c_{n-6} c_{n-7}\right)_{10}+\left(c_{n-8} c_{n-7} c_{n-6}\right)_{10}-\ldots(\bmod 7) và đồng dư thức tương tự cũng nhận được khi thay modulo 7 bởi modulo 13.13 .

Các đồng dư thức này cũng cho ta biết quy tắc về tính chia hết cho 7 hoặc 13. Chẳng hạn ta có N=858987905656879+5898N=8589879056 \equiv 56-879+589-8 theo cả modulo 7 và modulo 13 . Vì số trong vế phải các đồng dư thức này (bằng -242) là không chia hết cho cả 7 lẫn 13 nên NN không chia hết cho cả 7 lẫn 13.13 .

Các quy tắc với 27 và 37 được dựa trên tính chất 1001100 \equiv 1 theo mod27\bmod 27mod37\bmod 37. Từ đây ta nhận được các quy tắc tương tự với các trường hợp ở trên. Chẳng hạn ta có N=24540509509+540+24N=24540509 \equiv 509+540+24 theo mod27\bmod 27mod37\bmod 37. Số trong vế phải là 10731073 có thể viết thành 107373+11073 \equiv 73+1 theo mod27\bmod 27mod37\bmod 37. Số 7474 chia hết cho 3737 nhưng không chia hết cho 2727 và do đó số NN cũng chia hết cho 3737 nhưng không chia hết cho 2727.

Một số bài tập

1. Tìm hai chữ số tận cùng của số 210002^{1000}.

Lời giải. Ta có 210=102424(mod100)2^{10}=1024 \equiv 24(\bmod 100) vì vậy 22024276(mod100)2^{20} \equiv 24^{2} \equiv 76(\bmod 100). Nhưng 76276(mod100)76^{2} \equiv 76(\bmod 100) suy ra theo quy nạp 76k76(mod100),k=1,2,.76^{k} \equiv 76(\bmod 100), k=1,2, \ldots . Do đó 21000=220.50765076(mod100)2^{1000}=2^{20.50} \equiv 76^{50} \equiv 76(\bmod 100). Vậy hai chữ số tận cùng của 210002^{1000} là 7 và 6.

2. Chứng minh rằng ít nhất một trong sáu đồng dư thức sau là đúng (Erdos):

  1. x0(mod2)x \equiv 0(\bmod 2),
  2. x0(mod3)x \equiv 0(\bmod 3),
  3. x1(mod4)x \equiv 1(\bmod 4),
  4. x3(mod8)x \equiv 3(\bmod 8),
  5. x7(mod12)x \equiv 7(\bmod 12),
  6. x23(mod24)x \equiv 23(\bmod 24) với số nguyên xx bất kỳ.

Chứng minh. Nếu số nguyên xx không thỏa mãn cả 1) và 2) thì nó không chia hết cho 2 và 3 do đó có dạng 24t+r24 t+\mathrm{r} với tt là số nguyên và rr là một trong các số 1,5,7,11,13,17,19,231,5,7,11,13,17,19,23. Khi đó dễ dàng kiểm tra số x=24t+rx=24 t+r thỏa mãn các đồng dư thức 3),3),5),4),3),3),4),6) tương ứng.

Ghi chú. P.Erdos đã đặt ra bài toán sau đây: cho trước số tự nhiên nn, có tồn tại hay không tập hợp hữu hạn các đồng dư thức với modulo phân biệt lớn hơn nn mà mọi số nguyên thỏa mãn ít nhất một trong số chúng? H.Davenport đặt ra giả thuyết rằng câu trả lời là khẳng định nhưng sẽ không có một lời giải đơn giản. P.Erdos đã tự chứng minh giả thuyết này trong trường hợp n=2n=2 bằng cách sử dụng một số đồng dư thức với modulo là ước số của 120 . D.Swift đã cho lời giải với n=3n=3 bằng cách sử dụng các đồng dư thức với modulo là ước số của 2880. Giả thuyết đã được chứng minh với mọi n<20n<20 (Choi).

3. Tìm hai chữ số tận cùng của số 9999^{9^{9}}.

Lời giải. Theo modulo 100 thì 9281,9481261,9861221,9921.989,91089.919^{2} \equiv 81,9^{4} \equiv 81^{2} \equiv 61,9^{8} \equiv 61^{2} \equiv 21,9^{9} \equiv 21.9 \equiv 89,9^{10} \equiv 89.9 \equiv 1. Ta có 999(mod10)9^{9} \equiv 9(\bmod 10) suy ra 99=10k+99^{9}=10 k+9 với kk là số tự nhiên. Vì vậy từ 9101(mod100)9^{10} \equiv 1(\bmod 100) suy ra 999=910k+99989(mod100)9^{9^{9}}=9^{10 k+9} \equiv 9^{9} \equiv 89(\bmod 100) chứng tỏ chữ số tận cùng của 9999^{9^{9}} là 9 và chữ số liền trước đó là 8.8 .

4. Tìm hai chữ số tận cùng của số 9999^{9^{9}}.

Lời giải. Từ bài tập 3 suy ra 9999(mod10)9^{9^{9}} \equiv 9(\bmod 10) do đó 999=10t+99^{9^{9}}=10 t+9 với tt là số tự nhiên. Suy ra 999=910t+99989(mod100)9^{9^{9}}=9^{10 t+9} \equiv 9^{9} \equiv 89(\bmod 100). Vì vậy hai chữ số tận cùng của 9999^{9^{9}} là hai chữ số tận cùng của 9999^{9^{9}}.

Tài liệu tham khảo

  1. Lý thuyết sơ cấp của các số - W. SIERPINSKI
  2. cp-algorithms.com
  3. Handbook Competitive Programming - Antti Laaksonen
  4. Competitve programming 3 - Steven Halim, Felix Halim
  5. Giải thuật và lập trình - Thầy Lê Minh Hoàng

Bình luận

Bài viết tương tự

- vừa được xem lúc

Thuật toán quay lui (Backtracking)

Quay lui là một kĩ thuật thiết kế giải thuật dựa trên đệ quy. Ý tưởng của quay lui là tìm lời giải từng bước, mỗi bước chọn một trong số các lựa chọn khả dĩ và đệ quy.

0 0 38

- vừa được xem lúc

Các thuật toán cơ bản trong AI - Phân biệt Best First Search và Uniform Cost Search (UCS)

Nếu bạn từng đọc các thuật toán trong AI (Artificial Intelligence - Trí tuệ nhân tạo), rất có thể bạn từng nghe qua về các thuật toán tìm kiếm cơ bản: UCS (thuộc chiến lược tìm kiếm mù) và Best First Search (thuộc chiến lược tìm kiếm kinh nghiệm). Khác nhau rõ từ khâu phân loại rồi, thế nhưng hai th

0 0 152

- vừa được xem lúc

Sử dụng vector trong lập trình C++ - giải bài toán lập trình muôn thủa

Chào buổi tối mọi người, hôm nay lang thang trên mạng bắt gặp bài toán quen thuộc một thời của quãng đường sinh viên IT. Đấy chính là câu số 1 trong đề thi dưới đây:.

0 0 35

- vừa được xem lúc

MÔ PHỎNG THUẬT TOÁN VƯƠNG HẠO TRONG PROLOG

. 1. Các luật suy diễn trong thuật toán Vương Hạo. Luật 1: Chuyển vế các giả thuyết và kết luận ở dạng phủ định. Ví dụ: p v q, !(r ^ s), !q, p v r -> s, !p <=> p v q, p v r, p -> s, r ^ s, q.

0 0 76

- vừa được xem lúc

A* Search Algorithm

What is A* Search Algorithm. How it works. . Explanation.

0 0 43

- vừa được xem lúc

Python: Jump Search

Search là một từ khóa khá là quen thuộc đối với chúng ta. Hiểu theo đúng nghĩa đen của nó chính là "Tìm kiếm".

0 0 36