luogu P5283 [十二省联考2019]异或粽子
nmd,为什么\(HNOI\)没有这样的送温暖题qwq
所有区间的异或前k大,联想到超级钢琴,然后那题是区间和前k大,所以只要把对应的可持久化线段树改成可持久化\(Trie\)就行了
// luogu-judger-enable-o2
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<cmath>
#include<ctime>
#include<queue>
#include<map>
#include<set>
#define LL long long
#define db double
using namespace std;
const int N=5e5+10;
LL rd()
{
LL x=0,w=1;char ch=0;
while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
int s[N*35],ch[N*35][2],rt[N],tt;
void inst(int o1,int o2,LL x)
{
s[o1]=s[o2]+1;
for(int i=32;~i;--i)
{
int xx=x>>i&1;
ch[o1][xx]=++tt,ch[o1][xx^1]=ch[o2][xx^1];
o1=ch[o1][xx],o2=ch[o2][xx];
s[o1]=s[o2]+1;
}
}
LL quer(int o,LL x,int k)
{
LL an=0;
for(int i=32;~i;--i)
{
int xx=x>>i&1;
if(k<=s[ch[o][xx]]) o=ch[o][xx];
else an|=1ll<<i,k-=s[ch[o][xx]],o=ch[o][xx^1];
}
return an;
}
struct node
{
int i,j;
LL x;
bool operator < (const node &bb) const {return x<bb.x;}
}nw;
priority_queue<node> hp;
int n,k;
LL ans,a[N];
int main()
{
n=rd(),k=rd();
for(int i=1;i<=n;++i)
{
a[i]=a[i-1]^rd();
inst(rt[i]=++tt,rt[i-1],a[i-1]);
hp.push((node){i,i,quer(rt[i],a[i],i)});
}
while(!hp.empty()&&k--)
{
nw=hp.top();
hp.pop();
ans+=nw.x;
if(nw.j>1) --nw.j,nw.x=quer(rt[nw.i],a[nw.i],nw.j),hp.push(nw);
}
printf("%lld\n",ans);
return 0;
}