题目:
思路:既然要求区间内X异或a[i]的和是最大的那么就得令X异或a[i]的数尽量的大,而且异或时只有取反的时候每一位结果才可能为1(意思是只有取反这条路走才能让数字尽量的大)那么就统计区间内二进制每位0与1的个数,1多就取0使得区间异或和zho结果中该位1比较多,同理0多久取1,利用前缀和统计每位的前缀和并保存,在后面求区间时再减一下就好了
代码
#include <iostream>
using namespace std;
int a[100000]={0};
int bit[31][100000]= {0};
int main()
{
int n,i,q;
cin>>n;
for(i=1; i<=n; i++)
{
cin>>a[i];
}
for(i=1; i<=n; i++)
{
for(int k=0; k<31; k++)
{
if(a[i]&1)//如果a[i]在第k位是1的话,那么前缀和加1
{
bit[k][i]=bit[k][i-1]+1;
}
else bit[k][i]=bit[k][i-1]-1;//否则前缀和减1
a[i]>>=1;//a[i]等于a[i]往右移一位
}
}
cin>>q;
for(i=0; i<q; i++)
{
int l,r;
int x=0;
cin>>l>>r;
for(int k=0; k<31; k++)
{
int b=bit[k][r]-bit[k][l-1];
if(b<0)//如果b小于0的时候说明在这个区间内0比1多,所以这一位要变成1
x|=(1<<k);//1左移k位,就是在第k位添加一个1啦
}
cout<<x<<endl;
}
return 0;
}
京公网安备 11010502036488号