異或粽子
時間限制: 2 sec 記憶體限制: 512 mb
題目描述
因為考前一天發現t3是去年d班考過的題, 所以liu_runda決定臨時換題, 他找到了十二省聯考的包, 發現day1t1搬過來很合適, 就開始抄題面.
小粽是乙個喜歡吃粽子的好孩子。今天她在家裡自己做起了粽子。
小粽面前有n 種互不相同的粽子餡兒,小粽將它們擺放為了一排,並從左至右編號為1 到n。第i 種餡兒具有乙個非負整數的屬性值ai。每種餡兒的數量都足夠多,即小粽不會因為缺少原料而做不出想要的粽子。小粽準備用這些餡兒來做出k 個粽子。
小粽的做法是:選兩個整數數l, r,滿足1 ≤ l ≤ r ≤ n,將編號在[l, r] 範圍內的所有餡兒混合做成乙個粽子,所得的粽子的美味度為這些粽子的屬性值的異或和。(異或就是我們常說的xor 運算,即c/c++ 中的 ˆ 運算子)
小粽想品嚐不同口味的粽子,因此它不希望用同樣的餡兒的集合做出乙個以上的粽子。小粽希望她做出的所有粽子的美味度之和最大。請你幫她求出這個值吧!
輸入第一行兩個正整數n, k,表示餡兒的數量,以及小粽打算做出的粽子的數量。
接下來一行為n 個非負整數,第i 個數為ai,表示第i 個粽子的屬性值。
對於所有的輸入資料都滿足:1 ≤ n ≤ 5 × 105, 1 ≤ k ≤ min, 0 ≤ ai ≤4, 294, 967, 295。
輸出輸出一行乙個整數,表示小粽可以做出的粽子的美味度之和的最大值。
樣例輸入
3 21 2 3
樣例輸出
6最直接的想法都是n2的,但是顯然這個資料範圍需要其他的思路。
考慮取最大的一項,可以通過字首和+trie搞定(trie從高位到低位,每次貪心走盡可能與ask的數不同的那一側,得到的結果最大)
於是需要通過修改trie的做法使得可以查詢第k大的項。
然後用乙個堆維護答案,堆內一開始存放每個a[i]的第一大結果,當取出一項時,將第二大結果放入堆中。由於i,j和j,i會被取兩次,所以可以總共取出2k次,再將最終答案除以k(好像這個做法以外的方法需要使用可持久化trie)
注意由於我們將區間異或和轉化成兩個值的異或,所以需要將s[0]=0這一項也一併加入。
#pragma gcc optimize("ofast")
#include
//#include
//#include
//#include
typedef
long
long ll;
typedef
unsigned
long
long ull;
using
namespace std;
//using namespace __gnu_pbds;
const
int n=
5e5+5;
const
int m=
2e7+5;
int mod=
998244353
;//const ll inf=0x3f3f3f3f3f3f3f3f;
const
int inf=
0x3f3f3f3f
;const
double eps=
1e-10
;int trie[m][2
],sz[m]
,tot;
void
insert
(ll x)
sz[now]++;
}ll ask
(ll x,
int t)
if(t<=sz[trie[now]
[!p]])
else
}return ans;
}ll a[n]
,b[n]
;struct data
;bool
operator
<
(data a,data b)
priority_queueq;
intmain()
);} ll ans=0;
ask(a[0]
,3);
while
(k--))
;}cout
}
LG5283 異或粽子
共有 n 個數,選擇 k 個不同的 l,r 區間,使得它們的異或和最大 1 leq n leq 5 times 10 5,k leq 2 times 10 5 先會想到字首異或和,這樣求 l,r 區間異或和只需要用 pre l 1 oplus pre r 以此減少運算次數。然後由於是異或,又會想到 ...
十二省聯考 2019 異或粽子
題目鏈結 演算法 首先把字首異或和統計出來,再將得到的每乙個字首異或和 包括pre 0 0 塞進字典樹中,接下來有乙個貪心的思路 每當我拿著其中乙個異或和的值時,我在字典樹中盡可能找二進位制高位與其對應的位不相同的異或和,這樣兩者異或運算後,所得值最大。所以我們有了這樣乙個思路,對於每乙個pre i...
十二省聯考2019 異或粽子
點此看題 方法1 發現這道題k kk很小,先考慮用字首和表示異或和,建出一顆tire text tire 樹,然後把每個點的最優值丟進優先佇列中 因為其他值沒有這個值優 然後依次取出,再把次大值塞進去。由於每個區間會被統計兩次,所以我們找2k2k 2k次,最後把答案除以2 22即可。方法2 和k k...