兔子的区间密码

题目链接:牛客OI周赛8-普及组 NC20860

题目

链接:https://ac.nowcoder.com/acm/problem/20860
来源:牛客网

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

提示:异或指在二进制下一位位比较,相同则 0 不同则 1
例如$ 2=(010){2} 5=(101){2}$
所以 2 x o r 5 = ( 111 ) 2 = 7 2 xor 5 =(111)_{2} = 7 2xor5=(111)2=7

异或运算

异或,英文为exclusive OR。异或略称为XOR、EOR、EX-OR

异或(xor)是一个数学运算符。它应用于逻辑运算。异或的数学符号为“⊕”,计算机符号为“xor”。

异或也叫半加运算,其运算法则相当于不带进位的二进制加法:二进制下用1表示真,0表示假,则异或的运算法则为:0⊕0=0,1⊕0=1,0⊕1=1,1⊕1=0(同为0,异为1),这些法则与加法是相同的,只是不带进位,所以异或常被认作不进位加法。

异或巧用

  • 交换
static void swap(){
	a=a^b;
	b=b^a;
	a=a^b;
}

分析

思路:异或值最大,即每一位不同的尽可能的多。
如果L,R最高二进制位相同,则在区间[L,R]中所有数这一位都是相同的。不管我们选择哪两个数异或,这一位对答案都没有贡献。
如果我们找到了L,R第一位不同的数,那么L的x位为0,而R的x位为1。在区间[L,R]中,一定存在两个数为(011111…)(一共x-1个1)和(1000…)(一共x-1个0)。此时他们两个异或起来至最大。为1<<(x+1)-1。

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class Main{
	
	static int n,m,T;
	static StreamTokenizer sc=new StreamTokenizer(new BufferedInputStream(System.in));
	static PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
	public static int nextInt()throws IOException  {
		sc.nextToken();return (int)sc.nval;
	}
	public static long nextLong() throws IOException{sc.nextToken();return (long)sc.nval;}
	
	public static void main(String []args)throws IOException {
		T=nextInt();
		while(T-->0) {
			long l=nextLong();
			long r=nextLong();
			long a=l^r,ans=0;
			while(a!=0) {
				ans=ans*2+1;//将二进制转换为十进制。
				a>>=1;//将a右移一位,去比较下一位二进制位是否相同
			}
			System.out.println(ans);
		}
		
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值