题目:
思路:既然要求区间内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; }