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 1 s 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?
输入格式
The first line contains three integers n , l , r ( 0<=n<2^{50} , 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 the total number of 1 s in the range l to r in the final sequence.
Examples
Inputcopy | Outputcopy |
---|---|
7 2 5 | 4 |
Inputcopy | Outputcopy |
---|---|
10 3 10 | 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(0≤n≤250)。
- 对于序列中每一个 >1 的数,拆分成三个数 ⌊2n⌋,nmod2,⌊2n⌋ 并替换原数,直到序列中没有>1的数为止。
- 查询最终序列中 [l,r](1≤l,r) 中有多少 1。
- 同时 l,r 满足 0≤r−l≤105。
#include<bits/stdc++.h>
#define int long long
#define N 1000005
#define INF 0x3f3f3f3f
using namespace std;
int f(int n,int p)
{
int mid=1; //初始化mid为1,保证后续能够计算整个序列的中间位置
int y=n;
while(y>>1) //每次对y/2,mid*2,当y=0时,mid正好为中间位置
{
y>>=1;
mid<<=1; }
if(p<mid) return f(n>>1,p); //二分,如果所查询的位置在mid之前,那递归前半段,并继续查找p的位置
else if(p>mid) return f(n>>1,p-mid); //如果查询的位置在mid之后,那递归后半段
else return n&1; //如果找到了,那就对n取模,因为这个位置只能由n%2产生,就算之前是n/2的,那也是其中序列里n%2产生的
}
signed main()
{
ios::sync_with_stdio(false);
int n,l,r;
cin>>n>>l>>r;
int ans=0;
for(int i=l;i<=r;i++)
ans+=f(n,i); //递归要查询的每一个值
cout<<ans<<endl;
return 0;
}