Тооны битийг шалгах, асаах, унтраах, 1 битүүдийг нь тоолох жижиг аргууд.
Эхлээд жижиг бодлого
n = 13, k = 1 гэж өгөгдөв. 13 = 8 + 4 + 1 тул хоёртоор 1101.
1-р бит нь 0. Түүнийг асаавал 1111 = 15. Унтраавал юу ч өөрчлөгдөхгүй, 13 хэвээр. 1 бит 3 ширхэг. Хариу: 0 15 13 3.
Энгийн аргаас санаа руу
Битийг шалгах энгийн арга бол тоог 2-т дахин дахин хувааж, үлдэгдлийг нь харах. Энэ ажиллана, гэхдээ урт бөгөөд алдаа гаргахад амархан.
Компьютер битүүдтэй шууд ажилладаг >>, <<, &, |, ~ үйлдлүүдтэй. Тус бүр ганц алхам. Тэднийг хослуулбал битийг шалгах, асаах, унтраахыг нэг мөрөөр бичнэ. 1 битүүдийг тоолохдоо x &= x - 1 заль ашиглана: бүх битийг биш, зөвхөн 1 битүүдийг тойрно.
Нэр томьёо ба тэмдэглэгээ
- k-р бит
- Баруун талаас 0-ээс эхэлж тоолсон байрлал. 13-ыг
1101гэж бичихэд 0-р бит нь 1, 1-р бит нь 0. - 1 << k
- Зөвхөн k-р бит нь 1 байх тоо, өөрөөр хэлбэл 2ᵏ.
1 << 3 = 8. - & | ~
&(AND) хоёулаа 1 бол 1,|(OR) аль нэг нь 1 бол 1,~(NOT) бит бүрийг эсрэгээр нь эргүүлнэ.- x & (x − 1)
- x-ийн хамгийн баруун 1 битийг арилгасан тоо.
12 & 11 = 8. - cnt
- 1 битийн тоо. C++-д
__builtin_popcount(x)ижил утга буцаана.
Компьютер 13-ыг 00001101 гэж хадгална. Бит бүр 0 эсвэл 1 байна, баруун захын бит нь 0-р бит. Одоо 1-р битийг шалгаад, асаагаад, унтраая.
- Space тоглуулах
- ←→ алхам
- −+ хурд
- 1 бит
- Маск
- Шалгаж буй бит
- Өөрчлөгдсөн бит
- Хариу
Тэг ба нэг
Компьютер тоог 0, 1 гэсэн битүүдээр хадгалдаг. 13 = 8 + 4 + 1 тул 13-ыг 1101 гэж бичнэ. Бит бүр асаах, унтраах товч шиг.
Дараа нь юу болох вэ?
Оноо 0 / 00дараалсан зөв, хамгийн их 0
Animation нэг алхам дээр зогсоно. Дараа нь код юу хийх вэ? Таагаад оноо цуглуул! Нэвтрэх хэрэггүй, оноо чинь энэ төхөөрөмж дээр хадгалагдана.
Юунд хэрэгтэй вэ?
Олонлогийг ганц тоогоор хадгалах, Bitmask DP, хурдан тоолох зэрэгт хэрэглэнэ. Бит дээрх үйлдлийг компьютер хамгийн хурдан гүйцэтгэдэг.
Яаж ажилладаг вэ?
1. (n >> k) & 1: битүүдийг k байр баруун тийш шилжүүлээд хамгийн баруун битийг авна. Энэ бол k-р бит. 2. n | (1 << k): k-р битийг асаана. 1 << k гэдэг нь зөвхөн k-р бит нь 1 байх тоо. 3. n & ~(1 << k): k-р битийг унтраана. ~ бүх битийг эсрэгээр нь эргүүлнэ. 4. x &= x − 1: хамгийн баруун 1 битийг арилгана. x = 0 болтол давтахад loop 1 бит бүрт нэг л удаа эргэнэ. Оролт: n ба k. Гаралт: k-р бит, k-р битийг асаасан тоо, унтраасан тоо, 1 битийн тоо.
Яагаад зөв, хэр хурдан бэ?
x - 1 хийхэд хамгийн баруун 1 бит 0 болж, түүнээс баруун талын 0 битүүд бүгд 1 болно. Түүнээс зүүн талын битүүд өөрчлөгдөхгүй. Тиймээс x & (x - 1) яг тэр нэг битийг л арилгана. Loop 1 бит бүрт нэг удаа эргэж, x = 0 болоход зогсоно.
Шалгах, асаах, унтраах тус бүр O(1). Тоолох нь 1 битийн тоогоор эргэдэг: эерэг int-д хамгийн ихдээ 31 удаа. Сая тооны битийг тоолоход 31 сая хүрэхгүй алхам.
Түгээмэл алдаа
1 << kнь int. k ≥ 31 бол overflow болно. Том тоонд1LL << kгэж бич.- Үйлдлийн эрэмбэ:
n & 1 << k == 0гэвэл==эхэлж бодогдоно. Үргэлж хаалт тавь:((n >> k) & 1) == 0. ~(1 << k)нь бүх 32 битийг эргүүлдэг тул сөрөг тоо гарна. Үүнийг зөвхөн&үйлдэлтэй хамт ашигла.- Сөрөг x дээр
while (x > 0)loop огт ажиллахгүй. Сөрөг тоондunsignedэсвэл__builtin_popcountхэрэглэ.
Хязгаарын тохиолдол
- n = 0: k-р бит 0, асаавал 2ᵏ, унтраавал 0, cnt = 0. Loop нэг ч эргэхгүй.
- n = 255: 8 бит бүгд 1. Асаахад өөрчлөгдөхгүй, cnt = 8.
- k-р бит аль хэдийн 1 бол
n | (1 << k)нь n хэвээр. Аль хэдийн 0 болn & ~(1 << k)нь n хэвээр. - 2-ын зэрэг, жишээ нь 64: ганц 1 бит, loop нэг л эргэнэ.
Өөрийгөө шалга
6 & 5хэд вэ?Хариу харах
4.
110 & 101 = 100.n = 10, k = 3 бол программ юу хэвлэх вэ?
Хариу харах
1 10 2 2. 10 =1010тул 3-р бит 1. Асаахад 10 хэвээр, унтраахад 2, 1 бит хоёр ширхэг.n = 200 бол
x &= x - 1loop хэдэн удаа эргэх вэ?Хариу харах
3 удаа. 200-г хоёртоор бичвэл
11001000, 1 бит 3 ширхэг.
Гурван дадлага
Hint-ээ нээхээс өмнө өөрөө оролдоорой.
1.n = 22, k = 2 бол программ юу хэвлэхийг гараар бод.
Hint харах
22-ыг эхлээд хоёртоор бич.
Хариу ба тайлбар
22 =
10110. 2-р бит 1, асаахад 22 хэвээр, унтраахад 22 − 4 = 18, 1 бит 3 ширхэг. Хариу:1 22 18 3.2.k-р битийг эсрэгээр нь эргүүлдэг (1 бол 0, 0 бол 1 болгодог) мөр нэм.
Hint харах
XOR (
^) хоёр бит ялгаатай бол 1 гаргана.Хариу ба тайлбар
int t = n ^ (1 << k);k-р бит эргэж, бусад нь хэвээр үлдэнэ.3.x тэг биш бол түүний хамгийн баруун 1 битийг (жишээ нь 12-оос 4-ийг) ганц үйлдлээр ол.
Hint харах
Сөрөг тоо компьютерт
~x + 1хэлбэрээр хадгалагддаг.Хариу ба тайлбар
x & -x. 12 & −12 = 4. Fenwick Tree яг энэ заль дээр тулгуурладаг.
Жишээ
Оролт
13 1
Гаралт
0 15 13 3
Одоо өөрөө бодоод үз
Хичээл
Энэ сэдвийн хичээл удахгүй нэмэгдэнэ.