NC20860 兔子的区间密码
兔子的区间密码
https://ac.nowcoder.com/acm/problem/20860
题目大意
给定 ,求从
中任取两个数(可以相同)异或的最大值。多组数据。
题解
首先如果 就直接返回
,下面均讨论
的情况。
然后看 的最高二进制位是否相同,如果相同就表明
中所有数这一位都是相同的,这一个二进制位不会对答案造成任何影响,因为异或后一定会消掉。从而可以把最高那位减掉,对新的
继续求解。
如果不相同呢?设最高位代表 ,那么由于
,就可得到
且
。此时最优方案为令
与
异或,得到
。这就是结果。
一次求解的时间复杂度为 。
#include <bits/stdc++.h> #define REP(temp, init_val, end_val) for (int temp = init_val; temp <= end_val; ++temp) #define REPR(temp, init_val, end_val) for (int temp = init_val; temp >= end_val; --temp) using namespace std; typedef long long ll; ll l, r; void init(){ scanf("%lld%lld", &l, &r); } void solve(){ if (l == r){ printf("0\n"); return ; } REPR(i, 59, 0){ if ((l & (1ll << i)) != (r & (1ll << i))){ printf("%lld\n", (2ll << i) - 1ll); break; } if (l & (1ll << i)) l ^= (1ll << i), r ^= (1ll << i); } } int main(){ int T; scanf("%d", &T); while (T--){ init(); solve(); } return 0; }