BZOJ 5495: [2019省队联测]异或粽子 可持久化trie+堆
和超级钢琴,异或之三倍经验 $?$
堆+贪心素质三连 $?$
好无聊......
code:
#include <bits/stdc++.h> #define N 500006 #define ll long long #define setIO(s) freopen(s".in","r",stdin) // , freopen(s".out","w",stdout) using namespace std; char buf[100000],*p1,*p2; #define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++) ll rd() { ll x=0; char s=nc(); while(s<'0') s=nc(); while(s>='0') x=(ll)(((x<<2)+x)<<1)+s-'0',s=nc(); return x; } namespace trie { int tot; int cnt[N*42],ch[N*42][2]; int newnode() { return ++tot; } void Insert(int pre,int &x,ll v) { int now=x=newnode(),i; for(i=40;i>=0;--i) { int o=(1ll*(v>>i)&1); ch[now][o^1]=ch[pre][o^1]; ch[now][o]=newnode(); pre=ch[pre][o]; now=ch[now][o]; cnt[now]=cnt[pre]+1; } } ll query(int x,int y,ll z) { ll re=0; int i; for(i=40;i>=0;--i) { int o=(1ll*(z>>i)&1); if(ch[x][o^1]<ch[y][o^1]) re+=(1ll<<i),x=ch[x][o^1],y=ch[y][o^1]; else x=ch[x][o],y=ch[y][o]; } return re; } }; struct node { int o,l,r; ll val; int pos; node(int a=0,int b=0,int c=0,ll d=0,int e=0):o(a),l(b),r(c),val(d),pos(e){} bool operator<(node b) const { return b.val>val; } }; priority_queue<node>q; ll A[N],ar[N],id[N]; int rt[N]; set<int>S[N]; set<int>::iterator it; int main() { // setIO("input"); int i,j,n,k,ou=0; n=rd(),k=rd(); for(i=1;i<=n;++i) { A[i]=rd()^A[i-1]; id[i]=ar[i]=A[i]; trie::Insert(rt[i-1],rt[i],A[i]); } sort(ar+1,ar+1+n); for(i=1;i<=n;++i) id[i]=lower_bound(ar+1,ar+1+n,id[i])-ar; for(i=1;i<=n;++i) S[(int)id[i]].insert(i); for(i=0;i<n;++i) { int l=i+1,r=n; ll tmp=trie::query(rt[l-1],rt[r],A[i]); int idx=lower_bound(ar+1,ar+1+n,A[i]^tmp)-ar; int pos=*S[idx].lower_bound(l); q.push(node(i,l,r,tmp,pos)); } ll ans=0ll; while(ou<k) { node e=q.top(); q.pop(); ans+=(ll)e.val,++ou; int pos=e.pos; if(pos!=e.l) { ll tmp=trie::query(rt[e.l-1],rt[pos-1],A[e.o]); int idx=lower_bound(ar+1,ar+1+n,A[e.o]^tmp)-ar; int t=*S[idx].lower_bound(e.l); q.push(node(e.o,e.l,pos-1,tmp,t)); } if(pos!=e.r) { ll tmp=trie::query(rt[pos],rt[e.r],A[e.o]); int idx=lower_bound(ar+1,ar+1+n,A[e.o]^tmp)-ar; int t=*S[idx].lower_bound(pos+1); q.push(node(e.o,pos+1,e.r,tmp,t)); } } printf("%lld\n",ans); return 0; }