由于格里莎去年表现良好,新年前夕,戴德-莫罗兹带着一大包礼物来看望他!袋子里装着 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 ≤ k ≤ n ≤ 1018)。
输出
输出一个数字 —— 最大可能的异或和。
-
在k = 1的时候,我们只能够选择一个数,那怎么选才能最大 ? 当然直接选最大的。
-
在k > 1的时候。
此处明确异或的性质,即二进制数位相同为0,不同为1。
如果我们想要一个数最大,那么就是要让这个数的二进制数位有更多的1,在这里如果我们找到小于n的最大的2的m次方数,那么这个数表示出来就是: ( 100000000 … 000 ) 2 (100000000 \dots 000)_2 (100000000…000)2,那么我们想要这个数的所有数位都变成1该怎么办 ?
只需要让 ( 2 m ) (2^m) (2m) X O R XOR XOR ( 2 m − 1 ) (2^m - 1) (2m−1)。
这里的过程就是两个二进制数相互异或: ( 1000000 … 0000 ) 2 (1000000 \dots 0000)_2 (1000000…0000)2 X O R XOR XOR ( 0111111 … 1111 ) 2 (0111111 \dots 1111)_2 (0111111…1111)2
注意这里 k k k 大于等于2,那么一定能取得两个数,并且 2 m 2^m 2m 和 2 m − 1 2^m-1 2m−1 当然都是小于等于 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;
}