Anu-Has-a-Function

CodeForces Round # 618 div2 C题

Anu Has a Function

题干

Anu has created her own function f : f ( x , y ) = ( x ∣ y ) − y f : f(x,y)=(x|y)−y f:f(x,y)=(xy)y where || | denotes the bitwise OR operation. For example, f ( 11 , 6 ) = ( 11 ∣ 6 ) − 6 = 15 − 6 = 9 f(11,6)=(11|6)−6=15−6=9 f(11,6)=(116)6=156=9 . It can be proved that for any nonnegative numbers x x x and y y y value of f ( x , y ) f(x, y) f(x,y) is also nonnegative.

She would like to research more about this function and has created multiple problems for herself. But she isn’t able to solve all of them and needs your help. Here is one of these problems.

A value of an array a 1 , a 2 , … , a n a_1,a_2,\dots,a_n a1,a2,,an is defined as f ( f ( … f ( f ( a 1 , a 2 ) , a 3 ) , … a n − 1 ) , a n ) f(f(\dots f(f(a_1, a_2), a_3), \dots a_{n-1}), a_n) f(f(f(f(a1,a2),a3),an1),an)(see notes). You are given an array with not necessarily distinct elements. How should you reorder its elements so that the value of the array is maximal possible?

Input

The first line contains a single integer n ( 1 ≤ n ≤ 1 0 5 ) n (1 \le n \le 10^5 ) n(1n105).

The second line contains n n n integers a 1 , a 2 , … , a n ( 0 ≤ a i ≤ 1 0 9 ) a_1, a_2, \ldots, a_n ( 0 \le a_i \le 10^9 ) a1,a2,,an(0ai109). Elements of the array are not guaranteed to be different.

Output

Output n n n integers, the reordering of the array with maximum value. If there are multiple answers, print any.

解题思路

直觉上,我们可以判断出在二进制层面 f ( x , y ) f(x,y) f(x,y)运算的过程中不会出现某一个二进制位被借位的情况(因为一般情况下的减法有可能出现这种情况)

//这里是按照传统的二进制减法来理解,当然计算机实现减法是用补码啦

我们采用一种类似于数学归纳法的方式证明这个结论

x , y x,y x,y的最低位记作 x 0 , y 0 x_0,y_0 x0,y0,若 x 0 ∣ y 0 = 0 x_0|y_0=0 x0y0=0 x 0 = y 0 = 0 , f ( x 0 , y 0 ) = 0 x_0=y_0=0,f(x_0,y_0)=0 x0=y0=0,f(x0,y0)=0,若 x 0 ∣ y 0 = 1 且 x 0 = y 0 x_0|y_0=1\text{且}x_0=y_0 x0y0=1x0=y0,则减法也不会发生借位

x 0 ∣ y 0 = 1 且 x 0 = 1 , y 0 = 0 x_0|y_0=1且x_0=1,y_0=0 x0y0=1x0=1,y0=0显然不会借位,若 x 0 ∣ y 0 = 1 且 x 0 = 0 , y 0 = 1 x_0|y_0=1且x_0=0,y_0=1 x0y0=1x0=0,y0=1也是没有发生借位。

我们发现针对最低位不会发生借位,不难归纳出对于每一位也是这样的。那么这个函数可以写为按位运算的形式

f ( x , y ) = x y ˉ f(x,y)=x\bar{y} f(x,y)=xyˉ其中 y ˉ \bar{y} yˉ表示对y按位取反

那么 f ( f ( … f ( f ( a 1 , a 2 ) , a 3 ) , … a n − 1 ) , a n ) = a 1 a 2 ˉ a 3 ˉ … a n ˉ = a 1   a n d    ( a 2   o r   a 3   o r … a n ) f(f(\dots f(f(a_1, a_2), a_3), \dots a_{n-1}), a_n)=a_1\bar{a_2}\bar{a_3}\dots \bar{a_n}=a_1~and~\text{~}(a_2~or~a_3~or\dots a_n) f(f(f(f(a1,a2),a3),an1),an)=a1a2ˉa3ˉanˉ=a1 and  (a2 or a3 oran)

由或运算的分配律知整个式子的结果就是由 a 1 a_1 a1的选取决定的

那么我们怎么选取 a 1 a_1 a1呢?当然是暴力出奇迹啦!,每一个 a i a_i ai都计算一下就好了,这里要注意使用一下前缀和、后缀和的思想保存 [ a 1 , a i ] [a_1,a_i] [a1,ai]区间和 [ a j , a n ] [a_j,a_n] [aj,an]相或的结果。

#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=1e5+5;
int a[maxn],qzh[maxn],hzh[maxn];
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        qzh[i]=qzh[i-1]|a[i];
    }
    for(int i=n;i>=1;i--){
        hzh[i]=hzh[i+1]|a[i];
    }
    int ans=-1,t,maxi=0;
    for(int i=1;i<=n;i++){
        t=a[i]&~(qzh[i-1]|hzh[i+1]);
        if(t>ans){
            ans=t;
            maxi=i;
        }
    }
    cout<<a[maxi]<<" ";
    for(int i=1;i<=n;i++){
        if(i!=maxi)cout<<a[i]<<" ";
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值