題目鏈結
給定乙個長度為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函式對資料進行轉換 從資料庫中讀取二進位制資料...