HDU
来源:互联网 发布:疯狂原始人 知乎 编辑:程序博客网 时间:2024/06/06 00:26
题目链接:HDU - 5969
题意:找出区间[L, R]中的两个数x、y,使x|y(位或)最大。
题解:位或是二进制运算,二进制中只有0和1,要使位或最大,就要使R位或后的1尽可能的多。因为位或的性质,不可能位或后使数的最高位大于R。所以其中一个数必须是R。首先要知道,在剩下的数中能使R增加的1的位数是有限的。那么能增加多少呢?能使L与R出现的L的最高不同位之后的低位全部变成1。
例:R:10100010 能产生最大位或的数:R:10100010 位或结果:10111111
L:10011000 x:10011111
可以将上面R的绿色位全部变成1。
这是因为一个数x从L开始增大到R,x与R出现的x的最高不同位不能超过L与R的L的最高不同位。如样例中x与R最高不同位不能超过红色位。因为能产生最的位或的x必须满足与R的最高不同位之后的位全部是1,如紫色的部分,这样位或后能使R的相同部分全变成1,而如果此时让紫色位1继续增多,那么会使x大于R,不满足条件。
操作:
1.取K = R ^ L;这样能将R与L所有不同的位都标记出来。例中的K = 00111010
2.求出求出K的最高位的位数d(例K的蓝色位),令x = (1 << d) - 1。这样能使最高不同位后的位全部变成1。例中的x = 00011111
3.ans = R | x
#include <bits/stdc++.h>using namespace std;//求出最高位int digit(long long K){ int d = 0; while(K > 0){ K >>= 1; d++; } return d;}int main(){ int T; long long L, R, ans, K, x, d; scanf("%d", &T); while(T--){ scanf("%I64d%I64d", &L, &R); K = R ^ L; d = digit(K); x = (1LL << d) - 1; printf("%I64d\n", R | x); } return 0;}
阅读全文
2 0
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- HDU
- Mybatis中service层分页是如何实现的?
- JSP报错"Syntax error on token "=", @ expected"的完美解决方案
- HDU1253 基础BFS
- (3)sql 学习 :创建库,表,视图,索引,drop,alter,日期,IFNULL
- BFC
- HDU
- 三阶幻方口诀
- 百度前端学院task16总结
- Mac 通过 SSH 远程连接Linux服务器
- protobuf应用与原理详解
- python 面向对象高级编程
- 数据结构 二叉树的性质
- 归并排序
- 第5天