题目链接:牛客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);
}
}
}