1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| #include<queue> #include<cstdio> #include<cstring> #include<algorithm> using namespace std;
typedef long long ll; const int N=5e5+10;
int n,m; ll val[N],pre[N];
struct TRIE{ int ncnt,nxt[N*32][2],siz[N*32],rt; void Insert(int &u,const int &dep,const ll &num){ if(!u) u=++ncnt; siz[u]++; if(dep<0) return; Insert(nxt[u][num>>dep&1],dep-1,num); } ll Query(const int &u,const int &dep,const ll &num,const int &rnk){ if(dep<0) return 0; if(num>>dep&1) if(rnk<=siz[nxt[u][0]]) return Query(nxt[u][0],dep-1,num,rnk); else return Query(nxt[u][1],dep-1,num,rnk-siz[nxt[u][0]])|(1ll<<dep); else if(rnk<=siz[nxt[u][1]]) return Query(nxt[u][1],dep-1,num,rnk)|(1ll<<dep); else return Query(nxt[u][0],dep-1,num,rnk-siz[nxt[u][1]]); } }Tr;
struct DATA{ ll num; int idx,rnk; DATA(const ll &_n,const int &_i,const int &_r):num(_n),idx(_i),rnk(_r){} }; bool operator <(const DATA &a,const DATA &b){return a.num<b.num;}
inline ll Ri(){ register ll a=0,c=getchar(); while(c<'0' || '9'<c) c=getchar(); while('0'<=c && c<='9') a=(a<<1)+(a<<3)+c-'0',c=getchar(); return a; } priority_queue<DATA> que; int main(){ n=Ri(),m=Ri()*2; for(int i=1;i<=n;i++) pre[i]=pre[i-1]^(val[i]=Ri()); Tr.Insert(Tr.rt,31,0); for(int i=1;i<=n;i++) Tr.Insert(Tr.rt,31,pre[i]); for(int i=0;i<=n;i++){ ll res=Tr.Query(Tr.rt,31,pre[i],1)^pre[i]; que.push(DATA(res,i,1)); } ll ans=0; while(m--){ ans+=que.top().num; int thi=que.top().idx,rnk=que.top().rnk; que.pop(); if(rnk>n) continue; rnk++; ll res=Tr.Query(Tr.rt,31,pre[thi],rnk)^pre[thi]; que.push(DATA(res,thi,rnk)); } printf("%lld\n",ans/2); return 0; }
|