前言:我个人觉得这种与位运算的题,还是要自己去草稿纸上多写几种二进制数(8位即可)找找规律,多找说不定就找到了。 思路:举个栗子,00101001到00101110,前面相等的不可以动,不然就不在这个范围了,然后让不同的那一位为1的后面全为0(那一位为1中最小的,绝对在范围内),让那一位为0的后面全为1(总是比那一位为1的小,绝对在范围内)。综上,从高到低第一次不一样的开始,自身及其后面全为1就是答案 AC代码&思路:
#include<iostream>
using namespace std;
int main()
{
ios::sync_with_stdio(0);cin.tie(0);
int t;cin>>t;
long long l,r;
while(t--)
{
cin>>l>>r;
bool flag =0;
for(int i=62; i>=0; --i)//想想long long右移62位后的那一位是什么是能知道i从62开始递减,其实最好写成sizeof(l)*8-2,不然说不定脑子突然短路写成30了
{
if( (l>>i) != (r>>i) ) {cout<<((1LL << (i+1))-1)<<'\n'; flag=1; break;}
}
if(!flag) {cout<<0<<'\n';}//如果两个数一模一样就比了,一个数异或自身为0
}
return 0;
}
其实还可以这么写核心代码(提前判断两个数是否一样)
cin>>l>>r;
if(l == r) {cout<<0<<'\n';}
for(int i=62; i>=0; --i)
{
if( (l>>i) != (r>>i) ) {cout<<((1LL << (i+1))-1)<<'\n'; break;}
}