Subject to the effect:
Topic links: https://www.luogu.org/problemnew/show/P5283
given a sequence found
intervals
Such that the maximum interval and the XOR.
Ideas:
Do it first prefix XOR, so the problem is converted to find
of
such that
large as possible.
Notice
, so that if the elected
, then will choose again
. So we can ask the number of times
, so that each two successive query is a set of the same
. Divided by 2 final answer on the line.
We maintain a heap, will each
corresponding
biggest
thrown inside the reactor, each taken interrogation top of the stack, the next large
thrown into the heap.
for
seeking
making
as the first
large apparently can
maintenance. Each time the right to use to determine the value to the left and right subtrees.
So you can not use persistent
to the completion of this question. time complexity
。
Code:
#include <queue>
#include <cstdio>
#include <string>
#include <iostream>
#define mp make_pair
using namespace std;
typedef long long ll;
const int N=500010,LG=35;
int n,m,tot=1,trie[N*LG][2],cnt[N],size[N*LG];
ll a[N],ans;
priority_queue<pair<ll,int> > q;
ll read()
{
ll d=0;
char ch=getchar();
while (!isdigit(ch)) ch=getchar();
while (isdigit(ch))
d=(d<<3)+(d<<1)+(ll)ch-48LL,ch=getchar();
return d;
}
void insert(ll x)
{
int p=1;
for (int i=LG;i>=0;i--)
{
int id=(x>>(ll)i)&1;
if (!trie[p][id]) trie[p][id]=++tot;
p=trie[p][id];
size[p]++;
}
}
ll find(ll x,int k)
{
int p=1;
ll ans=0;
for (int i=LG;i>=0;i--)
{
int id=(x>>(ll)i)&1;
if (trie[p][id^1]&&size[trie[p][id^1]]>=k)
{
ans=(ans<<1)|1;
p=trie[p][id^1];
}
else if (trie[p][id])
{
k-=size[trie[p][id^1]];
ans<<=1;
p=trie[p][id];
}
}
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
insert(0); cnt[0]=1;
for (int i=1;i<=n;i++)
{
a[i]=read();
a[i]^=a[i-1];
insert(a[i]);
cnt[i]=1;
}
for (int i=0;i<=n;i++)
q.push(mp(find(a[i],1),i));
m*=2;
while (m--)
{
if (!q.size()) break;
ans+=q.top().first;
int i=q.top().second;
q.pop();
cnt[i]++;
if (cnt[i]<=n+1)
q.push(mp(find(a[i],cnt[i]),i));
}
cout<<ans/2LL;
return 0;
}