思路:查询出该区间内 每一个位置中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(); } }