BZOJ 5495: [2019省队联测]异或粽子 可持久化trie+堆

时间:2023-03-09 16:22:28
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;
}