Nowcoder.兔子的区间密码 ——位运算性质 异或性质

题目连接:登录—专业IT笔试面试备考平台_牛客网

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

解题思路:

如果left和right最高二进制位相同,则在区间[L,R]中所有数这一位都是相同的。不管我们选择哪两个数异或,这一位对答案都没有贡献。所以我们需要从高到底去找第一个不同的位,如果找到第一位不同的数,那么在区间[left,right]中,一定存在两个数为(011111…)和(1000…)。此时他们两个异或起来结果最大。要想让异或之后的结果最大,肯定从高位开始就要尽量大,也就是两个数的高位尽量不同。
如果lr的二进制位数不

同,首先高位补0补齐,然后看我们能否在r的最高位取1的时候r的最高是不是不一样(如果一样,那么这一位只能取这个值,异或之后就消掉了),一直到第一个不一样的位置,肯定是r的这一位是1,l的这一位是0,之后小的那个数每一位显然可以任取了,所以后面全部都可以做到一个取1一个取0,于是找到l和r二进制不同的最高位从这位开始全部都是1就是答案

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll read(){
   ll s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
   return s*w;
}
int main(){
	long long t;
	cin>>t;
	while(t--){
		long long l,r;
		cin>>l>>r;
		if(l==r)
		cout<<0<<endl;
		else{
		long long x=1ll<<62;
        while((l&x)==(r&x)) {
     		x>>=1;   	
		}
        x<<=1;
        cout<<x-1<<endl;
		}
	}
	return 0;
} 

00011=00100-1  小性质

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值