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; } }