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;
}