# bzoj4571: [Scoi2016]美味

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;

struct chairman
{
int lc,rc,c;
}tr[6100000];int trlen,rt[210000];
int maketree(int x,int l,int r,int p)
{
if(x==0)
{
x=++trlen;
tr[x].lc=tr[x].rc=0;
}
tr[x].c++;

if(l<r)
{
int mid=(l+r)/2;
if(p<=mid)tr[x].lc=maketree(tr[x].lc,l,mid,p);
else       tr[x].rc=maketree(tr[x].rc,mid+1,r,p);
}
return x;
}
int merge(int x,int y)
{
if(x==0||y==0)return x+y;
tr[x].c+=tr[y].c;
tr[x].lc=merge(tr[x].lc,tr[y].lc);
tr[x].rc=merge(tr[x].rc,tr[y].rc);
return x;
}
bool check(int x,int y,int ml,int mr,int l,int r)
{
if(l<0)l=0;
if(x==0&&y==0)return false;
if(ml==l&&mr==r)return (tr[y].c-tr[x].c)>0;

int mid=(ml+mr)/2;
if(r<=mid)  return check(tr[x].lc,tr[y].lc,ml,mid,l,r);
else if(mid+1<=l)return check(tr[x].rc,tr[y].rc,mid+1,mr,l,r);
else return check(tr[x].lc,tr[y].lc,ml,mid,l,mid)|check(tr[x].rc,tr[y].rc,mid+1,mr,mid+1,r);
}

int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
int n,Q,x;
scanf("%d%d",&n,&Q);
trlen=0;memset(rt,0,sizeof(rt));
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
rt[i]=maketree(rt[i],0,(1<<23)-1,x);
rt[i]=merge(rt[i],rt[i-1]);
}

while(Q--)
{
int g,d,st,ed;
scanf("%d%d%d%d",&g,&d,&st,&ed);

int L=-d,R=(1<<23)-1-d,ans=0;
for(int i=22;i>=0;i--)
{
int mid=(L+R)>>1;
int x=(g&(1<<i));
if(x==0)
{
if(check(rt[st-1],rt[ed],0,(1<<23)-1,mid+1,R))
ans+=(1<<i), L=mid+1;
else
R=mid;
}
else
{
if(check(rt[st-1],rt[ed],0,(1<<23)-1,L,mid))
ans+=(1<<i), R=mid;
else
L=mid+1;
}
}
printf("%d\n",ans);
}
return 0;
}

posted @ 2018-09-15 10:07  AKCqhzdy  阅读(105)  评论(0编辑  收藏  举报