HDU 5969 最大的位或
正文索引 [隐藏]
传送门:http://acm.split.hdu.edu.cn/showproblem.php?pid=5969
题解
因为是位或,所以我们肯定取右边界为其中的一个数字。然后我们先把另一个数字设为左边界,然后从大往小位挨个尝试去补另一个数字的这一位的0,如果能不就补,如此即可。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
//while(true) RP++; #include<cstdio> #define LL long long using namespace std; LL L,R; LL dow; inline LL lowbit(LL x){ return x&-x; } inline LL del(LL x,LL lm){ LL lt=lowbit(x); while(lt<lm && lt!=0){ x-=lt; lt=lowbit(x); } return x; } inline void solve(int T){ scanf("%I64d%I64d",&L,&R); dow=L; for (LL i=60;i>=0;i--){ if ((1LL<<i)>R) continue; if ((R&(1LL<<i))==0 && (dow&(1LL<<i))==0){ LL mask=del(dow,(1LL<<i)); if ((mask|(1LL<<i))<=R) dow=(mask|(1LL<<i)); } } printf("%I64d\n",R|dow); } int main(){ int T=0; while(scanf("%d",&T)!=EOF) for (int i=1;i<=T;i++) solve(i); return 0; } |

原文链接:HDU 5969 最大的位或
WNJXYKの博客 版权所有,转载请注明出处。
还没有任何评论,你来说两句吧!