Codeforces Round 456 (Div. 2) - B. New Year‘s Eve (位运算,Bitsmasks)

由于格里莎去年表现良好,新年前夕,戴德-莫罗兹带着一大包礼物来看望他!袋子里装着 n 颗来自老式面包店的糖果,每颗糖果都按照口味从 1 到 n 贴上标签。没有两颗糖果的口味是相同的。

糖果的选择直接影响到格里莎的幸福感。我们可以认为他应该吃最好吃的糖果 --但不是,节日的魔力颠覆了一切。重要的是美味的 xor 和,而不是普通的和!

整数序列 a 1 ,   a 2 ,   . . . ,   a m a_1, a_2, ..., a_m a1,a2, ...,am 的异或和定义为其所有元素的异或。在这里插入图片描述

Ded Moroz 警告格里莎他还有更多的房子要去,所以格里莎可以从袋子里拿走 不超过 k 的糖果。帮助格里沙确定他能获得的最大 xor 和(最大 xor 和意味着最大的快乐!)。

输入
唯一字符串包含两个整数 n n n k ( 1   ≤   k   ≤   n   ≤   1 0 18 ) k ( 1 ≤ k ≤ n ≤ 10^{18} ) k(1 kn 1018)

输出
输出一个数字 —— 最大可能的异或和。


  • 在k = 1的时候,我们只能够选择一个数,那怎么选才能最大 ? 当然直接选最大的。

  • 在k > 1的时候。
    此处明确异或的性质,即二进制数位相同为0,不同为1。
    如果我们想要一个数最大,那么就是要让这个数的二进制数位有更多的1,在这里如果我们找到小于n的最大的2的m次方数,那么这个数表示出来就是: ( 100000000 … 000 ) 2 (100000000 \dots 000)_2 (100000000000)2,那么我们想要这个数的所有数位都变成1该怎么办 ?
    只需要让 ( 2 m ) (2^m) (2m) X O R XOR XOR ( 2 m − 1 ) (2^m - 1) (2m1)
    这里的过程就是两个二进制数相互异或: ( 1000000 … 0000 ) 2 (1000000 \dots 0000)_2 (10000000000)2 X O R XOR XOR ( 0111111 … 1111 ) 2 (0111111 \dots 1111)_2 (01111111111)2
    注意这里 k k k 大于等于2,那么一定能取得两个数,并且 2 m 2^m 2m 2 m − 1 2^m-1 2m1 当然都是小于等于 n n n 的,所以这两个数一定能够取到。

CODE:

#include<bits/stdc++.h>
using namespace std;
#define ll long long

int lowbit(ll x){
    return x&-x;
}

int main(){
    ll n,k;
    cin >> n >> k;

    if(k == 1){
        cout << n << endl;
        return 0;
    }

    int l = 0,r = 60;
    while(l < r){
        int mid = l + r + 1 >> 1;
        if((1ll << mid) <= n)l = mid;
        else r = mid - 1;
    }

    cout << (1ll << l+1)-1 << endl;
    

    return 0;
}
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值