思路:查询出该区间内 每一个位置中1的个数 然后根据1多还是0多进行对比 来确定X当前位置应该为1还是0
具体思路:
首先我们需要去确定记录每个位置的1的个数。我们可以用前缀和来完成,建立二维数组来存储前缀中各位1的个数,然后通过r位置的减去l-1位置的个数即可得到l到r区间内每位中1的个数。
其次如果要是1的个数小于区间长度的话,说明1是少数,既然1是少数,那我们就让X的该位置为1,这样异或0的个数就会更多从而使值更大。
如果1大于等于区间的话,就让该位置为0,因为X尽量小,所以等于放在这个位置。
最后通过各位是1或者是0来计算X
import java.math.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.*;
public class Main {
public static void main(String args[])throws IOException
{
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
in.nextToken();
int n = (int)in.nval;
long a[] = new long[n+1];
int num[][] = new int[n+1][32];
long x=0;
int p=1;
for(int i=1;i<=n;i++)
{
in.nextToken();
x = (long)in.nval;
a[i] = x;
p=1;
for(int j=1;j<32;j++)
num[i][j]+=num[i-1][j];
while(x>0)
{
if((x&1)==1)
num[i][p]++;
p++;
x>>=1;
}
}
in.nextToken();
int q = (int)in.nval;
while(q-->0)
{
in.nextToken();
int l = (int)in.nval;
in.nextToken();
int r = (int)in.nval;
int b[] = new int[32];
long ans=0,temp=1;
for(int j=1;j<32;j++)
{
if(2*(num[r][j]-num[l-1][j])<r-l+1)
b[j]=1;
else{
b[j]=0;
}
}
for(int j=1;j<32;j++)
{
ans+=(temp*b[j]);
temp*=2;
}
out.println(ans);
}
out.flush();
}
}
京公网安备 11010502036488号