思路

可以用位运算和前缀和的相关知识。
要让X异或a[i]求和最大SUM,则SUM的每一位都是1,我们需要求的是X的每一位该取0还是1。
我们可以用一个二维数组a[i][j]记录前i个数第j位是1的个数,这样我们就能知道L~R范围内某一位的0多还是1多。
运用异或的性质我们知道,在0多的情况下X那一位该取1,在1多的情况下X那一位该取0;
而0和1一样多的时候,根据题意X尽可能小,就取0。

代码

#include<bits/stdc++.h>
using namespace std;

int n,q,a,l,r;
int sm1[100005][32];
//sm[i][j]:第i个数前面第j位有多少个0/1;

int main(){
    scanf("%d",&n);
    memset(sm1,0,sizeof(sm1));
    for(int i=1;i<=n;i++){
        scanf("%d",&a);
        int j=0;
        while(a){
            if(a&1) sm1[i][j]++;
            a>>=1;
            j++;
        }
        for(int j=0;j<=30;j++){ //求前缀和 
            sm1[i][j]+=sm1[i-1][j];
        }
    }
    scanf("%d",&q);
    for(int i=1;i<=q;i++){
        scanf("%d%d",&l,&r);
        int ans=0,len=r-l+1;
        for(int j=0;j<=30;j++){
            if(2*(sm1[r][j]-sm1[l-1][j])<len)
        //l到r在j位上0的个数之和比1多,那么X的j位是1 
                ans+=(1<<j); // 
        }
        cout<<ans<<endl;
    }
    return 0;
}