题目链接:https://ac.nowcoder.com/acm/contest/332/G
看到这道题的时候就直接先暴力了一发,当然我知道暴力过不了,所以就在找规律,然后把每一位对应的按位或的和列了出来,如下图1-20
其中出现了很多个相同的数,如果把这些重复的数省去,时间复杂度就会降低很多,其实列出来以后就能发现当一个数按位或一个比它大的数的时候它才会变,所以我们对于a和b,依次枚举ans按位或ans+1,直到大于等于b就好了。其实原理也很简单,对于一个数按位或一个比它大1的数,根据按位或的性质,其实就是在这个数的最高位前加一个1。
AC代码:
#include
#define ll long long
using namespace std;
int main()
{
ll a,b;
while(scanf("%lld%lld",&a,&b) != EOF){
if(a == b){
printf("%lld\n", a);
continue;
}
ll ans = a | (a + 1);
while(ans < b){
ans |= (ans + 1);
}
printf("%lld\n", ans);
}
return 0;
}