题目传送门(内部题141)
输入格式
输入文件包含多组测试数据,第一行为一个正整数$T$,表示数据组数。
接下来$T$行,每行两个正整数$l,r$。数据保证$l\leqslant r$成立。
输出格式
输出$T$行,每行一个正整数,为满足条件的$x,y$进行或运算后的最大值,即输出$\max(x\ or\ y)$。
样例
样例输入:
3
1 10
1023 1024
233 322
样例输出:
15
1023
511
数据范围与提示
对于$40\%$的数据,满足$r\leqslant 500$。
对于$70\%$的数据,满足$r\leqslant 10^6$。
对于$100\%$的数据,满足$1\leqslant l\leqslant r\leqslant 10^{18},1\leqslant T\leqslant 1,000$。
题解
首先,将$l$和$r$都转化为二进制。
如果其在二进制下位数不一样,每一位都能是$1$,那么答案一定是$1<<R-1$,其中$R$为$r$的二进制位数。
如果位数相等,从高往低第一个不一样的位往后都可以是$1$,而前面的是什么就只能是什么了。
时间复杂度:$\Theta(T\times\log r)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h> using namespace std; long long L,R,ans; int l[100],r[100],tl,tr; void get() { tl=tr=ans=0; while(L){l[++tl]=(L&1);L>>=1LL;} while(R){r[++tr]=(R&1);R>>=1LL;} } int main() { int T;scanf("%d",&T); while(T--) { scanf("%lld%lld",&L,&R);get(); if(tl==tr) { int res; for(int i=tl;i;i--){if(l[i]!=r[i])break;res=i;} ans=(1LL<<(res-1))-1; for(int i=res;i<=tl;i++)if(l[i])ans+=(1LL<<(i-1)); } else ans=(1LL<<tr)-1; printf("%lld\n",ans); } return 0; }
rp++