Code for 1 (codeforces-768B)

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 n, l, r (0 ≤ n < 250, 0 ≤ r - l ≤ 105, r ≥ 1, l ≥ 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

inputCopy
7 2 5
outputCopy
4
inputCopy
10 3 10
outputCopy
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.

题意:

将一个数每次可以分成n/2,n%2,n/2,直到仅由0和1组成的数列,求这个数列给定的区间所有值之和。

思路:

分治。很显然,一个数n最后的数列长度为大于等于n的最小的(2^x)-1,这样就可以得知数列的长度len和分治的区间为1~len,然后依次递归下去。
这里我一开始的思路是分到当前n的值<2的时候进行治而求和,但是超时了,于是对于当前区间已经在所求区间外的情况进行了剪枝,就可以过2^50的数据了。

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <list>
#include <cmath>
#include <algorithm>
#define MST(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;
ll n, L, R;
ll solve(ll n, ll left, ll right) {
    if (left > R || right < L) return 0;
    if (n < 2) {
        if (left >= L && right <= R) return n;
        else return 0;
    }
    ll mid = (left + right) >> 1;
    return solve(n / 2, left, mid - 1) + solve(n % 2, mid, mid) + solve(n / 2, mid + 1, right);
}
int main() {
    cin >> n >> L >> R;
    ll len = 1;
    while (len < n) len = len * 2 + 1;
    cout << solve(n, 1, len) << endl;
}

猜你喜欢

转载自blog.csdn.net/white_yasha/article/details/80642707
今日推荐