题解 | #兔子的区间密码#
兔子的区间密码
https://ac.nowcoder.com/acm/problem/20860
#include<bits/stdc++.h>
#include<iostream>
using namespace std;
typedef unsigned long long ll;
inline void read(ll& a)
{
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();
}
a = s * w;
}
int main()
{
int t;
cin >> t;
ll l, r;
for (int x = 0; x < t; x++)
{
read(l);
read(r);
if (l == r)
{
cout << 0 << endl;
continue;
}
int dif;
for (int i = 63; i >= 0; i--)
{
//if ((l & (1 << i)) != (r & (1 << i)))
if(((l>>i)&1)!= ((r >> i) & 1))
{
dif = i;
break;
}
}
cout << (1LL << (dif + 1)) - 1 << endl;
// int y=dif+1;
//cout<<(((r >> i) << i) ^ (((r >> i) << i) - 1))<<endl;;
}
return 0;
}
重点:
- 输入数据较大,要想不超时,用快速读入法。
- 思路:R恒大于等于L,R如果和L不同位数(即R比L多一位)则区间内两数异或最大值一定可以为111...11(L的位数个1);R如果和L位数相同,则区间内两数异或最大值一定可以凑成111...11(位数-1个1)。 总体规律就是:从高位到低位找到L和R第一个不同的位,从该位开始到低位全1就是所求答案。
- 1默认是int类型,因此想要靠移位操作获得i(i>32)位为1的数,应该用(1LL<<(i-1)),1LL是类型为long long的1。 4、L==R时直接输出0