最大的位或 HDU - 5969 <bitset>

转载自: https://blog.csdn.net/qq_40508713/article/details/81387034

## 最大的位或 HDU - 5969 ##

B君和G君聊天的时候想到了如下的问题。 
给定自然数l和r ,选取2个整数x,y满足l <= x <= y <= r ,使得x|y最大。 
其中|表示按位或,即C、 C++、 Java中的|运算。 
Input 
包含至多10001组测试数据。 
第一行有一个正整数,表示数据的组数。 
接下来每一行表示一组数据,包含两个整数l,r。 
保证 0 <= l <= r <= 1018。 
Output 
对于每组数据输出一行,表示最大的位或。 
Sample Input 

1 10 
0 1 
1023 1024 
233 322 
1000000000000000000 1000000000000000000 
Sample Output 
15 

2047 
511 
1000000000000000000


刚开始做这个题的时候通过观察发现对于第一组样例,将其转换为二进制后 
R 10———->1010 
15———->1111 
根据题目要求可以利用异或反推出 x=5 5|10 = 15 
5————>0101 
由此我猜了一下可以将右边界转为二进制后找到最高位的1然后将最高位后所有0变为1 
然后wa了 
重新整理后发现 
L 100——–>0110 0100 
R 101——–>0110 0101 
如果按照以上规律求得的res = 0111 1111 = 127 
根据题目要求可以利用异或反推出 x=26 超出了左边界,所以不能直接用这个规律。 
那么根据上面的推导可以得出以下结论:要找到左右边界二进制下最高不同位,将此后所有位标为1。 
这里使用了STL中的bitset,bitset是用来进行一些状态储存的操作。类似于一个标记数组,又类似于状压里面的二进制。bitset可以访问指定下标的bit位。 
所以我们可以通过遍历找到最高不同位的下标,用(1LL << 下表)求得X的值

需要调用bitset库。

  • 一些常用操作
  • 进行一些与二进制相同的操作
  • b<<1;//b整体左移
  • b|=10; //b或 101

其他操作请移步bitset总结

#include <iostream>
#include <bitset>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;

int main()
{
    int t;
    ull x,y;
    cin >> t;
    while(t--){
        cin >> x>>y;
        bitset<200> w (x^y);
        int i = 199;
        while(w[i]!=1&& i>=1)  i--;//找到最高位不相等的第一位
        ull a = (1LL<<i)-1;
        cout << (y|a) <<endl;
    }
    return 0;
}

(还是觉得这么写很牛逼hhh,stl大法好)

猜你喜欢

转载自blog.csdn.net/weixin_42754600/article/details/81407211
今日推荐