题目:
样例输入:
5
1 10
0 1
1023 1024
233 322
1000000000000000000 1000000000000000000
样例输出:
15
1
2047
511
1000000000000000000
分析:
题意很明白,就不再多说,分析一下我们要求的最大,可以这样想,表示成2进制,从高到低,能是1必然是1,即使是1之后会出现许多0也比0优,那么我们就考虑哪一位能是1.
很显然的贪心,我们考虑一下如何贪心即可。我们想一想这两个数,如果l和r只有前len位一样,那么没办法两个数字必然前len位和l和r一样,那么或出来的数字前len位也和l和r一样,我们考虑len+1位,第len+1一般会是r为1,l为0(除非只有len位),那么我们就可以让一个数前len位和l一样,后面是100。。。这个数字不会比r大,让另一个数前len位也和l一样,后面是011。。。这个数字不会比l小,而这两个数字或之后是前len位后面加上111。。。,显然将会是最优。
代码:
#include <cstdio> #include <cstring> const int maxn=64+10; bool a[maxn]; bool b[maxn]; long long po(int x){ long long ans=1; for(int i=1;i<=x;i++) ans*=2ll; return ans; } int main(){ int t; scanf("%d",&t); for(int jsjs=1;jsjs<=t;jsjs++){ memset(a,0,sizeof(a)); memset(a,0,sizeof(a)); long long l,r; scanf("%lld%lld",&l,&r); int w=1; while(l){ a[w]=l&1; l>>=1; w++; } w=1; while(r){ b[w]=r&1; r>>=1; w++; } long long ans=0; for(int i=w-1;i>=1;i--){ if(a[i]==b[i]&&a[i]) ans+=po(i-1); else if(a[i]!=b[i]){ ans+=po(i)-1; break; } } printf("%lld ",ans); } return 0; }