https://ac.nowcoder.com/acm/problem/18979

题意:
有n个数a1, a2, ..., aN,给出m个询问,每次询问区间[l,r],请找出一个数x使得x异或区间每个数的和最大。

分析:
异或运算,异或1取反,异或0不变,为了使结果最大,因此如果某个数位为1,那么我们对其异或0,如果某个数位为0,那么我们对其异或1取反,如此贪心取得最大值。
因此对于区间[l,r]的每个数,我们只需求出每个数位上0多还是1多,如果1多,该数位为0,反之,则为1.对于求[l,r]区间每个数位1的数量,我们只需要用前缀和预处理下就行了,即a[r]-a[l-1],而对于区间数位01总数量,可以用下标r-l+1进行表示。

代码:

#include<algorithm>
#include<iostream>
typedef long long ll;
using namespace std;
ll n,m,i,j,ans,k,l,r;
ll a[100005][32];
int main()
{
    cin>>n;
    for(i=1;i<=n;i++){
        cin>>k;
        for(j=0;j<=30;j++){
            a[i][j]=a[i-1][j];//前缀和记录每位1的数量
            if((k>>j)&1) a[i][j]++;
        }
    }
    cin>>m;
    while(m--){
        cin>>l>>r;
        ans=0;
        for(i=0;i<=30;i++){
            ll sum=r-l+1;
            if((a[r][i]-a[l-1][i])*2<sum) ans+=(1<<i);
        }
        cout<<ans<<endl;
    }
}