可以先简化一下问题 看作是给你一个b 问再区间l r 内的数与之异或的最大值
显然是从最高位到最低位开始贪心
主席树负责查询区间内是否有这个数
#include<bits/stdc++.h> using namespace std; #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define ll long long #define see(x) (cerr<<(#x)<<'='<<(x)<<endl) #define inf 0x3f3f3f3f #define CLR(A,v) memset(A,v,sizeof A) ////////////////////////////////// const int N=2e5+10; int T[N],t[N<<5],lson[N<<5],rson[N<<5],ncnt; void upnode(int x,int l,int r,int pre,int &pos) { pos=++ncnt; t[pos]=t[pre]+1;lson[pos]=lson[pre];rson[pos]=rson[pre]; if(l==r)return ;int m=(l+r)>>1; if(x<=m)upnode(x,l,m,lson[pre],lson[pos]); else upnode(x,m+1,r,rson[pre],rson[pos]); } int qsum(int L,int R,int l,int r,int pre,int pos) { if(l>r||L>R)return 0; if(L<=l&&r<=R)return t[pos]-t[pre]; int ans=0,m=l+r>>1; if(L<=m)ans+=qsum(L,R,l,m,lson[pre],lson[pos]); if(R>m)ans+=qsum(L,R,m+1,r,rson[pre],rson[pos]); return ans; } int a[N],n,m; int main() { scanf("%d%d",&n,&m);int maxx=0; rep(i,1,n) scanf("%d",&a[i]),maxx=max(maxx,a[i]); rep(i,1,n) upnode(a[i],0,maxx,T[i-1],T[i]); int b,x,l,r; while(m--) { int ans=0; scanf("%d%d%d%d",&b,&x,&l,&r); repp(i,23,0) { int c=(b>>i)&1; if(c&&!qsum(ans-x,ans-x+(1<<i)-1,0,maxx,T[l-1],T[r]))ans+=(1<<i); else if(!c&&qsum(ans-x+(1<<i),ans-x+(1<<i)+(1<<i)-1,0,maxx,T[l-1],T[r]))ans+=(1<<i); } printf("%d ",ans^b); } return 0; }