题目:
小a有N个数a1, a2, ..., aN,给出q个询问,每次询问给出区间[L, R],现在请你找到一个数X,使得
1、
2、最大,
表示异或操作。
做法:
由于异或位于位之间是不影响的,所以我们可以分别考虑X每个位选0还是选1。若[L,R]区间的数中第i位,0的数量>1的数量,则X的第i位选1比0优。反之,选0比选1优。
所以通过前缀和处理,快速得到[L,R]区间中的数每个位的1的数量,然后每个位贪心选0或1,问题解决。
代码:
#include <bits/stdc++.h>
#define debug(a) cout << #a ": " << a << endl
#define IOS ios::sync_with_stdio(false), cin.tie(0)
using namespace std;
typedef long long ll;
const int N = 1e5 + 7;
int a[N], cnt[N][35];
int solve(int l, int r){
int len = r-l+1, ans = 0;
for (int i = 30; i >= 0; --i){
int one = cnt[r][i]-cnt[l-1][i];
int zero = len-one;
if (zero > one){
ans |= (1<<i);
}
}
return ans;
}
int main(void){
IOS;
int n; cin >> n;
for (int i = 1; i <= n; ++i){
cin >> a[i];
for (int j = 30; j >= 0; --j){
if ((a[i]>>j)&1){
cnt[i][j] = cnt[i-1][j]+1;
}else{
cnt[i][j] = cnt[i-1][j];
}
}
}
int q; cin >> q;
while (q--){
int l, r; cin >> l >> r;
cout << solve(l, r) << endl;
}
return 0;
}
京公网安备 11010502036488号