代码:
#pragma GCC optimize(2)
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=(int)1e6+10;
struct Node
{
int num,lch,rch;
Node():num(0),lch(-1),rch(-1){}
}tree[N*20];
int tot,a[N],rt[N],qnum;
void init()
{
tot=0;
}
void pushup(int p)
{
tree[p].num=tree[tree[p].lch].num+tree[tree[p].rch].num;
}
int build(int l,int r)
{
int p=tot++;
tree[p]=Node();
if(l==r)
{
tree[p].num=0;
return p;
}
int mid=(l+r)>>1;
tree[p].lch=build(l,mid);
tree[p].rch=build(mid+1,r);
pushup(p);
return p;
}
int add(int p,int l,int r,int x,int y,int z)
{
int cp=tot++;
tree[cp]=Node();
if(x<=l&&r<=y)
{
tree[cp].num=tree[p].num+r-l+1;
return cp;
}
int mid=(l+r)>>1;
if(x<=mid)
{
tree[cp].lch=add(tree[p].lch,l,mid,x,y,z);
}
else
{
tree[cp].lch=tree[p].lch;
}
if(mid<y)
{
tree[cp].rch=add(tree[p].rch,mid+1,r,x,y,z);
}
else
{
tree[cp].rch=tree[p].rch;
}
pushup(cp);
return cp;
}
void query(int L,int R,int x,int y,int l,int r)
{
if(L<=l&&r<=R)
{
qnum+=tree[y].num-tree[x].num;
return;
}
int mid=(l+r)>>1;
if(mid>=L)
{
query(L,R,tree[x].lch,tree[y].lch,l,mid);
}
if(mid<R)
{
query(L,R,tree[x].rch,tree[y].rch,mid+1,r);
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
init();
int n,m;
scanf("%d%d",&n,&m);
rt[0]=build(1,(int)1e6);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
rt[i]=add(rt[i-1],1,(int)1e6,a[i],a[i],a[i]);
}
int ans=0;
while(m--)
{
int L,R,p,k;
scanf("%d%d%d%d",&L,&R,&p,&k);
L^=ans;
R^=ans;
p^=ans;
k^=ans;
int l=0,r=(int)1e6;
while(l<r)
{
int mid=(l+r)>>1;
qnum=0;
query(max(p-mid,1),min(p+mid,(int)1e6),rt[L-1],rt[R],1,(int)1e6);
if(qnum>=k)
{
r=mid;
}
else
{
l=mid+1;
}
}
printf("%d\n",ans=l);
}
}
return 0;
}
蔡弈文
全部评论