其他分享
首页 > 其他分享> > # NC20860 兔子的区间密码

# NC20860 兔子的区间密码

作者:互联网

NC20860 兔子的区间密码

题目

题目描述

有一只可爱的兔子被困在了密室了,密室里有两个数字,还有一行字:
只有解开密码,才能够出去。
可爱的兔子摸索了好久,发现密室里的两个数字是表示的是一个区间 \([L,R]\)
而密码是这个区间中任意选择两个(可以相同的)整数后异或的最大值。
比如给了区间 \([2,5]\) 那么就有 \(2,3,4,5\) 这些数,其中 \(2 \oplus 5=7\) 最大,所以密码就是\(7\) 。
兔子立马解开了密室的门,发现门外还是一个门,而且数字越来越大,兔子没有办法了,所以来求助你。
提示:异或指在二进制下一位位比较,相同则 \(0\) 不同则 \(1\)
例如 \(2=(010)_2\) , \(5=(101)_2\)
所以 $ 2 \oplus 5 =(111)_2=7$

输入描述

第一行一个数 \(T\) ,表示数据组数。
接下来 \(T\) 行,每行两个数 \(L,R\) , 表示区间 \([L,R]\) 。

输出描述

输出共 \(T\) 行每行一个整数,表示 \([L,R]\) 的密码。

示例1

输入

5
1 10
2 3
3 4
5 5
2 5

输出

15
1
7
0
7

备注

对于 \(30\%\) 的数据
\(1 ≤ T ≤ 10\)
\(0 ≤ L ≤ R ≤ 100\)
对于另外 \(10\%\) 的数据
\(L=R\)
对于 \(70\%\) 的数据
\(1 ≤ T ≤ 10\)
\(0 ≤ L ≤ R ≤ 50000\)
对于 \(100\%\) 的数据
\(1 ≤ T ≤ 10000\)
\(0 ≤ L ≤ R ≤ 10^{18}\)
(对于 \(100\%\) 的数据) 输入数据较大,请使用快速读入。

题解

思路

知识点:贪心,位运算。

要使两个数异或最大,最好的解就是形如 \(111111\) ,\(000000\) 的异或。

我们只要找到第一对能够产生 \(1 \oplus 0\) 的数位,即异或结果的最高位。这里可以用区间端点异或得到。

注意到区间是连续的,如果产生如上述的一对,则至少有以这位开始的二进制,如在第5位,则有 \(100000\) ,则必有 \(011111\) ,因此异或最大值是 \(111111\) 。

因此找到最高位后,只要将后面填满 \(1\) 即可。

注意这里的 \(long \ long\) 位数。

时间复杂度 \(O(1)\)

空间复杂度 \(O(1)\)

代码

#include <bits/stdc++.h>

using namespace std;

int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t;
    cin >> t;
    while (t--) {
        long long l, r;
        cin >> l >> r;
        long long ans = l ^ r;
        for (int i = 62;i >= 0;i--) {
            if ((ans >> i) & 1) {
                ans = (1LL << i + 1) - 1;
                break;
            }
        }
        cout << ans << '\n';
    }
    return 0;
}

标签:NC20860,10,long,密码,异或,兔子,区间
来源: https://www.cnblogs.com/BlankYang/p/16384117.html