您的位置:首页 > 运维架构

codeforces - Goodbye2015B - New Year and Old Property

2016-01-15 11:19 260 查看
B. New Year and Old Property

time limit per test
2 seconds

memory limit per test
256 megabytes

input
standard input

output
standard output

The year 2015 is almost over.

Limak is a little polar bear. He has recently learnt about the binary system. He noticed that the passing year has exactly one zero in its representation in the binary system — 201510 = 111110111112.
Note that he doesn't care about the number of zeros in the decimal representation.

Limak chose some interval of years. He is going to count all years from this interval that have exactly one zero in the binary representation. Can you do it faster?

Assume that all positive integers are always written without leading zeros.

Input

The only line of the input contains two integers a and b (1 ≤ a ≤ b ≤ 1018) —
the first year and the last year in Limak's interval respectively.

Output

Print one integer – the number of years Limak will count in his chosen interval.

Sample test(s)

input
5 10


output
2


input
2015 2015


output
1


input
100 105


output
0


input
72057594000000000 72057595000000000


output
26


Note

In the first sample Limak's interval contains numbers 510 = 1012, 610 = 1102, 710 = 1112, 810 = 10002, 910 = 10012 and1010 = 10102.
Two of them (1012 and 1102)
have the described property.

说是模拟也不是,说不是模拟,又有好多需要考虑的点,总之调教场的题目嘛,质量越来越高【越来越不会做QAQ】

题意:给两个十进制数字 a 和 b, 把他们转换成二进制后,问 a 与 b 之间(包括 a, b)的二进制数,有多少个数二进制形式只含一个0
最开始没有考虑转换成二进制后两数位数相同,导致直接跪了一发

总体思路嘛:先把 a , b 转换成二进制,然后如果位数不等,就把中间的位数符合条件的直接加起来(每个位数上都 = 二进制位数 - 1,看题了都懂),再算 a , b 所在位数上 a之后(flag1), b 之前(flag2)符合条件的数;如果位数相同,则求出flag1, flag2后再减去该位数上的符合条件数,就是a, b 之间符合条件的个数啦。有一点就是,b符不符合条件需要单独求,a可以直接算进flag1中,但是b不行,必须单独判断

还是有点开心的,现在看到题目已经不会只揪着“暴力”了,开始考虑“方法”了,哈哈

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <stdlib.h>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <set>
using namespace std;

int main()
{
long long a, b;
while(scanf("%I64d%I64d", &a, &b) != EOF){
int sa[70], sb[70];
long long x = a, y = b;
int ka = 0, kb = 0;  // a,b 二进制有多少位
int flag = 0;  //判断b符合不符合条件
while(a){
sa[ka++] = a % 2;
a = a / 2;
}
while(b){
sb[kb++] = b % 2;
b = b / 2;
if(sb[kb - 1] == 0) flag++;
}
int ans = 0;
if(x != y){   //  a != b
for(int i = ka; i < kb - 1; i++){
ans = ans + i;
}
int flag1 = 0;  // a这个位数上,a之后符合条件的
for(int i = ka - 1; i >= 0; i--){
if(sa[i] == 0){
flag1 = i + 1;
ans += flag1;
break;
}
}
int flag2 = 0;  //  b这个位数上,b之前符合条件的
for(int i = kb - 1; i >= 0; i--){
if(sb[i] == 0){
flag2 = kb - i - 2;
ans += flag2;
break;
}
}
if(flag == 1)  //  如果b符合条件,+1咯
ans ++;
if(flag == 0)  //  =0是什么状况?果断表明b二进制全是1啊,把这个位数上的全加上!
ans = ans + kb - 1;
if(ka != kb)
printf("%d\n", ans);
else{
ans = ans - ka + 1;  // ka = kb  减去这个位数上的咯,毕竟加了两遍
printf("%d\n", ans);
}
}
else{    // a = b
if(flag == 1)
printf("1\n");
else
printf("0\n");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: