按位贪心即可。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define gc getchar()
#define gv(x,p) (((x)>>p)&1)
#define N 200010
#define M 100010
#define LOG 18
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
inline int inn()
{
int x,ch;while((ch=gc)<'0'||ch>'9');
x=ch^'0';while((ch=gc)>='0'&&ch<='9')
x=(x<<1)+(x<<3)+(ch^'0');return x;
}
struct segment{
int l,r,mx;segment *ch[2];
}*rt;int a[N];
int build(segment* &rt,int l,int r)
{
rt=new segment,rt->l=l,rt->r=r,rt->mx=0;
int mid=(l+r)>>1;if(l==r) return 0;
return build(rt->ch[0],l,mid),build(rt->ch[1],mid+1,r);
}
inline int push_up(segment* &rt)
{ return rt->mx=max(rt->ch[0]->mx,rt->ch[1]->mx); }
int update(segment* &rt,int p,int v)
{
int l=rt->l,r=rt->r,mid=(l+r)>>1;
if(l==r) return rt->mx=max(rt->mx,v);
return update(rt->ch[p>mid],p,v),push_up(rt);
}
int query(segment* &rt,int s,int t)
{
int l=rt->l,r=rt->r,mid=(l+r)>>1;
if(s<=l&&r<=t) return rt->mx;int ans=0;
if(s<=mid) ans=max(ans,query(rt->ch[0],s,t));
if(mid<t) ans=max(ans,query(rt->ch[1],s,t));
return ans;
}
struct Q{
int b,x,l,r,id;
inline bool operator<(const Q &q)const
{ return r<q.r; }
}q[M];int ans[M];
int main()
{
int n=inn(),m=inn();
for(int i=1;i<=n;i++) a[i]=inn();
for(int i=1;i<=m;q[i].id=i,i++)
q[i].b=inn(),q[i].x=inn(),
q[i].l=inn(),q[i].r=inn();
sort(q+1,q+m+1),build(rt,1,300010);
for(int i=1,c=0;i<=m;i++)
{
while(c+1<=q[i].r) c++,update(rt,a[c]+1,c);
for(int j=LOG-1,tmp,b,id,x;j>=0;j--)
{
ans[id=q[i].id]|=(1<<j),b=q[i].b,
x=q[i].x,tmp=((ans[id]^b)>>j)<<j;
int ql=max(tmp-x,0),qr=tmp+(1<<j)-1-x;
if(qr<0||query(rt,ql+1,qr+1)<q[i].l) ans[id]^=(1<<j);
}
}
for(int i=1;i<=m;i++) printf("%d\n",ans[i]);return 0;
}