小糉是一個喜歡吃糉子的好孩子。今天她在家裏本身作起了糉子。node
小糉面前有 $n$ 種互不相同的糉子餡兒,小糉將它們擺放爲了一排,並從左至右編號爲 $1$ 到 $n$。第 $i$ 種餡兒具備一個非負整數的屬性值 $a_i$。每種餡兒的數量都足夠多,即小糉不會由於缺乏原料而作不出想要的糉子。小糉準備用這些餡兒來作出 $k$ 個糉子。ios
小糉的作法是:選兩個整數數 $l,r$,知足 $1\le l\le r\le n$,將編號在 $[l,r]$ 範圍內的全部餡兒混合作成一個糉子,所得的糉子的美味度爲這些糉子的屬性值的**異或**和。(異或就是咱們常說的 $\mathrm{xor}$ 運算,即 C/C++ 中的 `^` 運算符或 Pascal 中的 `xor` 運算符)ide
小糉想品嚐不一樣口味的糉子,所以它不但願用一樣的餡兒的集合作出一個以上的糉子。spa
小糉但願她作出的全部糉子的美味度之和最大。請你幫她求出這個值吧!code
Solblog
前綴和完後至關於求兩點xor和的前k大。ci
有一個很好的想法:考慮左端點,先把和這個左端點xor最大的右端點放進堆裏,而後每次取堆頂,並接着把次大的放進去。get
也就是後面的答案必定會由前面的答案得來。string
之後想這種區間問題,能夠多從端點的角度考慮問題,固定一個端點,另外一個統計,取最大等等。it
而後查第k大就可持久化trie實現。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<algorithm> 6 #include<cmath> 7 #include<queue> 8 #define maxn 500005 9 #define ll long long 10 using namespace std; 11 int n,K,cnt,rt[maxn]; 12 ll a[maxn],ans; 13 struct node{ 14 int ch[2],sz; 15 }tr[maxn*42]; 16 struct no{ 17 int x,kth;ll v; 18 }; 19 bool operator <(no a,no b){ 20 return a.v<b.v; 21 } 22 priority_queue<no>q; 23 int get(int w,ll v){ 24 return ((1LL<<w)&v)>0; 25 } 26 void ins(int w,int &k,int la,ll v){ 27 if(!k)k=++cnt; 28 if(w<0){ 29 tr[k].sz=tr[la].sz+1;return; 30 } 31 int f=get(w,v); 32 ins(w-1,tr[k].ch[f],tr[la].ch[f],v); 33 tr[k].ch[f^1]=tr[la].ch[f^1]; 34 tr[k].sz=tr[tr[k].ch[0]].sz+tr[tr[k].ch[1]].sz; 35 } 36 ll ask(int w,int k,int la,ll v,int kth){ 37 if(w<0)return 0; 38 int f=get(w,v); 39 int s=tr[tr[k].ch[f^1]].sz-tr[tr[la].ch[f^1]].sz; 40 if(w<=5){ 41 //printf("%d %d v=%d Kth=%d s=%d\n",w,k,v,kth,s); 42 } 43 if(s>=kth)return ask(w-1,tr[k].ch[f^1],tr[la].ch[f^1],v,kth)+(1LL<<w); 44 else return ask(w-1,tr[k].ch[f],tr[la].ch[f],v,kth-s); 45 } 46 int main(){ 47 cin>>n>>K; 48 ins(31,rt[0],rt[0],0); 49 for(int i=1;i<=n;i++){ 50 scanf("%lld",&a[i]); 51 a[i]^=a[i-1]; 52 ins(31,rt[i],rt[i-1],a[i]); 53 } 54 for(int i=0;i<=n;i++){ 55 no t;t.kth=1;t.x=i;t.v=ask(31,rt[n],rt[i],a[t.x],1); 56 //cout<<t.x<<' '<<t.v<<endl; 57 q.push(t); 58 }int co=0; 59 while(!q.empty()){ 60 no t=q.top();q.pop(); 61 ans+=t.v;t.v=ask(31,rt[n],rt[t.x],a[t.x],t.kth+1);t.kth++; 62 co++;if(co==K)break; 63 q.push(t); 64 } 65 cout<<ans<<endl; 66 return 0; 67 }