问题描述
Claris非常喜爱位运算,尤其是异或(XOR),因为它具有很多优美的性质。他有四个正整数a,b,c,d,满足a≤b且c≤d。他想选择两个整数x,y,满足a≤x≤b且c≤y≤d,使得x XOR y的值最大。但是他不知道该怎么做,所以请你告诉他x XOR y的最大值是多少。
输入描述
有多组测试数据,第一行一个整数T(1≤T≤10,000),表示测试数据的组数。对于每组测试数据: 仅一行,四个整数a,b,c,d(1≤a,b,c,d≤1018),相邻两个整数之间有一个空格隔开。
输出描述
对于每组测试数据,仅一行,一个整数,即x XOR y的最大值。
输入样例
2 1 2 3 4 5 7 13 15
输出样例
6 11
Hint
在第一组数据中,当且仅当x=2,y=4,x XOR y取得最大值。 在第一组数据中,当且仅当x=5,y=14或x=6,y=13,x XOR y取得最大值。
#include<iostream> #include<cstdio> using namespace std; int main(){ int Cas; cin>>Cas; long long a,b,c,d; long long sumx,sumy; long long temp; while(Cas--){ sumx = 0;//a <= sumx <= b sumy = 0;//c <= sumy <=d //并没有规定 b < c或 a < d scanf("%I64d%I64d%I64d%I64d",&a,&b,&c,&d); for(int i = 62; i >= 0; i--){ temp = 1; temp = temp << i;//使得temp都是10000000……(二进制)的形式来比较最高位 if(temp + sumy <=d &&temp +sumx <= b ){ if(temp + sumx < a && temp + sumy < c){//如果temp+sum<最小范围,那么该位必须为1 sumx = sumx + temp; sumy = sumy + temp; } else if(temp + sumx < a) sumx = sumx + temp; else if(temp + sumy < c) sumy = sumy + temp; else sumx = sumx + temp;//当temp + sum 在取值范围之内,那么只需一位为1, //另一位为0即可 ,方可使得异或最大 } else if(temp + sumy <= d) sumy = sumy + temp; else if(temp + sumx <= b) sumx = sumx + temp; //最后一句是因为b有可能是最大的数时,最先判断就是它 } long long ans = sumx^sumy; printf("%I64d\n",ans); } return 0; }