https://ac.nowcoder.com/acm/problem/18979
题意:
有n个数a1, a2, ..., aN,给出m个询问,每次询问区间[l,r],请找出一个数x使得x异或区间每个数的和最大。
分析:
异或运算,异或1取反,异或0不变,为了使结果最大,因此如果某个数位为1,那么我们对其异或0,如果某个数位为0,那么我们对其异或1取反,如此贪心取得最大值。
因此对于区间[l,r]的每个数,我们只需求出每个数位上0多还是1多,如果1多,该数位为0,反之,则为1.对于求[l,r]区间每个数位1的数量,我们只需要用前缀和预处理下就行了,即a[r]-a[l-1],而对于区间数位01总数量,可以用下标r-l+1进行表示。
代码:
#include<algorithm>
#include<iostream>
typedef long long ll;
using namespace std;
ll n,m,i,j,ans,k,l,r;
ll a[100005][32];
int main()
{
cin>>n;
for(i=1;i<=n;i++){
cin>>k;
for(j=0;j<=30;j++){
a[i][j]=a[i-1][j];//前缀和记录每位1的数量
if((k>>j)&1) a[i][j]++;
}
}
cin>>m;
while(m--){
cin>>l>>r;
ans=0;
for(i=0;i<=30;i++){
ll sum=r-l+1;
if((a[r][i]-a[l-1][i])*2<sum) ans+=(1<<i);
}
cout<<ans<<endl;
}
}
京公网安备 11010502036488号