题意
有一个长度为的数组,每次询问一个区间
,找一个
,使得
最大。
分析
我们考虑每一位,假设我们区间的长度为,有
个数在这位上是
,三个数是
,那么
的这一位选
的贡献会更大,因为异或之后这一位就会有
个
,
个
。
所以我们可以根据区间的每一位的
的个数来决定
的这一位的取值。
具体一点就是:
多放
,
多放
,一样多放
。
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
#define int long long
const int inf = 0x3f3f3f3f;
const int maxn = 101110;
const int M = 1e9+7;
int n,m;
int a[maxn][32];
int b[32];
void solve(int l,int r)
{
int len = r-l+1;
int res = 0;
for(int j = 0,x; j < 31; j++)
{
x = a[r][j] - a[l-1][j]; //1的个数
if(x < (len+1)/2) res += b[j]; //1多放0,0多放1,一样多放0
}
cout<<res<<endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n;
b[0] = 1;
for(int j = 1; j < 31; j++)
{
b[j] = b[j-1]*2;
}
for(int i = 1,x; i <= n; i++)
{
cin>>x;
for(int j = 0; j < 31; j++)
{
a[i][j] = a[i-1][j];
if(x&b[j]) a[i][j]++;
}
}
cin>>m;
for(int i = 1,l,r; i <= m; i++)
{
cin>>l>>r;
solve(l,r);
}
return 0;
} 
京公网安备 11010502036488号