14938異或粽子

2021-10-04 19:24:32 字數 2109 閱讀 5790

異或粽子

時間限制: 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...