CodeForces

来源:互联网 发布:excel数据清洗 编辑:程序博客网 时间:2024/06/05 05:35

题目链接:http://codeforces.com/problemset/problem/768/B点击打开链接


B. Code For 1
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Jon fought bravely to rescue the wildlings who were attacked by the white-walkers at Hardhome. On his arrival, Sam tells him that he wants to go to Oldtown to train at the Citadel to become a maester, so he can return and take the deceased Aemon's place as maester of Castle Black. Jon agrees to Sam's proposal and Sam sets off his journey to the Citadel. However becoming a trainee at the Citadel is not a cakewalk and hence the maesters at the Citadel gave Sam a problem to test his eligibility. 

Initially Sam has a list with a single element n. Then he has to perform certain operations on this list. In each operation Sam must remove any element x, such that x > 1, from the list and insert at the same position  sequentially. He must continue with these operations until all the elements in the list are either 0 or 1.

Now the masters want the total number of 1s in the range l to r (1-indexed). Sam wants to become a maester but unfortunately he cannot solve this problem. Can you help Sam to pass the eligibility test?

Input

The first line contains three integers nlr (0 ≤ n < 2500 ≤ r - l ≤ 105r ≥ 1l ≥ 1) – initial element and the range l to r.

It is guaranteed that r is not greater than the length of the final list.

Output

Output the total number of 1s in the range l to r in the final sequence.

Examples
input
7 2 5
output
4
input
10 3 10
output
5
Note

Consider first example:

Elements on positions from 2-nd to 5-th in list is [1, 1, 1, 1]. The number of ones is 4.

For the second example:

Elements on positions from 3-rd to 10-th in list is [1, 1, 1, 0, 1, 0, 1, 0]. The number of ones is 5.


仔细观察可以发现 每个数被拆分成的最终序列是有规律的 这里以10举例

先将该数用二进制表示 1010

观察序列 发现二进制中的第一位的1位于1 3 5 7 9 11 13 15的位置

第二位的0位于2 6 10 14

第三位的1位于4 12

第四位的0位于8

将1010这个二进制数的每一位附上权值 每一位对应为1 2 4 8 从左到右位置为 0 1 2 3 (其实就是2的次方对应关系)

于是可以发现 对于序列中任意一个位置的值 都具有以下规律

设当前位置为position 

position的值对应于 position的因子中最大的2的N次方数 即为该数二进制的第N位的值

有点难懂 还是举10的例子

对于序列的第3位 他的因子中最大的2的N次方数为1 即N=0 所以为二进制1010的第0位 也就是第一个1

对于序列的第6位 她的因子中最大的2的N次方数为2 即N=1 所以对应1010的第一个0

。。。。。。12。。。。。。。。。。。。。。。4 即N=2 所以对应第三位 也就是第二个1

找出规律之后 代码就很简单了

因为范围不大 因此枚举他需要的区间的每个位置 根据规律计算当前的数是不是1

#include <iostream>#include <stdio.h>#include <limits.h>#include <stack>#include <algorithm>#include <queue>#include <string.h>#include <set>using namespace std;vector<long long int > s;int main(){   long long int n,l,r;   cin >> n >> l >> r;   while(n!=0)   {       s.push_back(n%2);       n/=2;   }   long long int cnt=0;   reverse(s.begin(),s.end());   s.push_back(0);   for(long long int i=l;i<=r;i++)   {        long long int j=0;        long long int mid=i;        while(mid%2==0)            j++,mid/=2;        if(s[j]==1)            cnt++;   }   cout << cnt;}




原创粉丝点击