位運算 lowbit運算

2021-09-01 13:29:09 字數 1029 閱讀 3846

位運算裡有一種十分基礎的運算:lowbit運算。

lowbit(n)定義為非負整數n在二進位制表示下「最低為的1及其後邊所有的0」構成的數值。例如n=10的二進位製表

示為(2)1010, 則lowbit(n)=2=(2)10。

————摘自《演算法競賽高階指南》

lowbit(n)的公式為:lowbit(n) = n & (~n + 1) = n & (-n)。下面事推導過程:首先將n的二進位制數去反,則原來是1的位置就變成了0,原來是0的位置就變成了1。然後再將取反的數加一。我們知道,二進位制數加一,則是乙個「遇0變1,遇1進製」過程。那麼原來的n的末尾的1以及1後面的一串0,取反變為乙個0後面跟一串1時,再加一則會將這一串二進位制數的1變成0,最前方的0變為1.比如:~101000 + 1 = 010111 + 1 = 011000。然後得到的數除了lowbit的那一串,其它部分都與原數n不同,所以我們再將n&得到的數,那些不同的部分就會全部變為0,而相同的部分則保持不變,這些不變的部分就是我們要求的lowbit(n)。

lowbit運算如何輸出整數二進位制下所有為1的位?我們只需要求出lowbit(n),然後在n=0之前不斷把n賦值位n-lowbit(n),再將表示當前lowbit(n)的log以2為底的n的對數輸出,便可以完成了。不過c++裡並沒有進行對數運算的函式(除了自然對數),所以我們需要進行預處理,將log以2為底的2的k次方的對數存起來,然後每次lowbit運算時只需要查一下陣列就可以了。為了優化時間複雜度,我們可以使用hash來將2的k次方對映到陣列的乙個下標,查詢的複雜度就可以優化位o(1)了。最直接的hash做法就是在hash[2^k]=k,不過空間複雜度就會特別大。這裡可以用乙個有技巧的做法,∀k∈[0, 35],st.2^k mod 37互不相等,且恰好取遍整數1~36(來自《演算法競賽高階指南》)。

附上**:

#include #include using namespace std;

int main()

printf("\n");

} return 0;

}

位運算 深入理解並證明 lowbit 運算

比如當 n 5 的時候,5 的二進位制是 0101 所以有 lowbit 5 1 比如當 n 10 的時候,10 的二進位制是 1010,所以有 lowbit 10 2 lowbit運算 c c 實現語句 1 函式 int lowbit int x 2 巨集定義 define lowbit x x ...

位運算(1) 初識位運算

前段時間數電課學了些進製轉換,還有與或非等邏輯運算,如今再來看看位運算,倒輕鬆了不少。很早就想寫些非總結性部落格了,奈何還是太懶。也也不知怎的突然又來了興致,趕忙寫下這篇部落格。廢話不多說,今天準備總結總結關於位運算的知識。程式中的所有數在計算機記憶體中都是以二進位制的形式儲存的,即0 1兩種狀態,...

位運算子和位運算

一 按位與 運算子 1 運算規則 參加運算的兩個 資料,按二進位進行 與 運算,如果兩個相應的二進位都為1,則該位的結果值為1,否則為0,即 0 0 0,0 1 0,1 0 0,1 1 1.2 用途 1 清零 運算物件 原來的數中為1的位,新數中相應位為0。2 取乙個數中某些指定位。如想要取乙個整數...