BZOJ4245 OR XOR(二進位制貪心)

2021-09-24 21:08:19 字數 1299 閱讀 7272

題目鏈結

給定乙個長度為n的序列a[1],a[2],...,a[n],請將它劃分為m段連續的區間,設第i段的費用c[i]為該段內所有數字的異或和,則總費用為c[1] or c[2] or ... or c[m]。請求出總費用的最小值。

input

第一行包含兩個正整數n,m(1<=m<=n<=500000),分別表示序列的長度和需要劃分的段數。

第一行包含n個整數,其中第i個數為a[i](0<=a[i]<=10^18)。

output

輸出乙個整數,即總費用的最小值。

sample input

3 2

1 5 7

sample output3

hint

第一段為[1],第二段為[5 7],總費用為(1) or (5 xor 7) = 1 or 2 = 3。

有n個數,分成m組,組內異或,然後組間或,得到的數最小是多少

從二進位制的角度看,最後得到的數最小,高位盡可能的是0。如果最高位可以是0,就該為是0,然後判斷下一位;如果不能是0,只能是1,就是1了,ans加上這一位。貪心的先讓最高位為0。

判斷某一位能否為0,因為是或運算得到的,所以每一組該位都必須是0。也就是說,n個數可以分成m組,每個組異或後該位是0。這裡通過或的特點進行優化,如果第一組是0,第二組也是0,那麼這兩組或運算也是0。可以用陣列記錄字首異或和,如果前2個數異或是0,前5個數異或也是0,那麼第3、4、5異或和也一定是0。該位可以為0,首先所有的異或得是0(所有組為0,再異或一定是0),並且為0的個數要大於等於m,才能分夠m個組。

由於要先保證高位為0,所以再把字首異或和為1的位置標記,以後就不能作為右邊界。

然後處理下一位。

或為0  --->  全部為0;

分組,組內異或為0  --->  異或字首和為0。

參考:

#include #define ll long long

using namespace std;

ll a[500010],ans;

int vis[500010];

int m,n;

int main()

for(int i=60;i>=0;i--)

}else ans |= (1ll<

}printf("%lld\n",ans);

return 0;

}

操作二進位制寫入二進

操作二進位制 寫入二進位制 1 宣告變數 sqlite3 stmt stat 2 把sql語句解析到stat結構中去 sqlite3 prepare 3 繫結替換 sqlite3 bind blob 4 儲存到資料庫 int result sqlite3 step 5 釋放stat結構 sqlite...

bzoj1992鬼谷子的錢袋 二分亂搞 二進位制

time limit 10 sec memory limit 162 mb submit 3223 solved 2333 鬼谷子非常聰明,正因為這樣,他非常繁忙,經常有各諸侯車的特派員前來向他諮詢時政。有一天,他在咸陽遊歷的時候,朋友告訴他在咸陽最大的拍賣行 聚寶商行 將要舉行一場拍賣會,其中有一...

mysql儲存二進位制 mysql 儲存二進位制資料

晚上小研究了下mysql儲存於讀取二進位制資料的功能。關鍵步驟為以下三點 最重要的一點 儲存二進位制資料的表的型別需要是blob型別 按長度不同分為tiny,media,long 插入二進位制資料時需要利用mysql real escape string函式對資料進行轉換 從資料庫中讀取二進位制資料...