# Codeforces#399 B. Code For 1 二叉树中序遍历的规律

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.

【分析】：

（这一步可以通过位运算 i&-i 直接得出编号i属于哪一层，例如i=12，i&-i = 4，即i在从下数第log2（4）+1层）

【代码-方法1】：

``````#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
map<ll,ll>M;
ll get1(ll x)//求得以x为根的二叉树有多少个1
{
ll res=0;
for(int i=0;x;i++){
if(x%2)res+=(1ll<<i);
x>>=1;
}
return res;
}
ll dfs(ll n,ll &r,ll &ans)//二叉树中序遍历
{
int k=log2(n);//求得n的二进制数长度-1
if(r>(1ll<<k)-1)//左子树全部包含在内，无需遍历
{
ans+=M[n/2];
r-=(1ll<<k)-1;
}
else if(r>0&&n>1)
dfs(n/2,r,ans);
if(r>0){
ans+=n%2;
r--;
}
if(r>(1ll<<k)-1)//右子树全部包含在内，无需遍历
{
ans+=M[n/2];
r-=(1ll<<k)-1;
}
else if(r>0&&n>1)
dfs(n/2,r,ans);
}
int main()
{
ll n,l,r,y;
while(cin>>n>>l>>r)
{
M.clear();
for(ll t=n;t;t>>=1)//预处理每个状态的子树中1的数量
M[t]=get1(t);
ll ans1=0,ans2=0;
dfs(n,r,ans1);
dfs(n,--l,ans2);
cout<<ans1-ans2<<endl;
}
}
``````

【代码-方法2】：

``````#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<int>v;
int main()
{
ll n,l,r;
while(~scanf("%lld",&n)){
v.clear();
scanf("%lld%lld",&l,&r);
if(n==0){
puts("0");continue;
}
ll ceng=log2(n),ans=0;
while(n){
v.push_back(n%2);//每一层的值
n/=2;
}
for(ll i=l;i<=r;++i){
ans+=v[ceng-log2(i&-i)];//每一项的层数
}
cout<<ans<<endl;
}
return 0;
}
``````

原文作者：B树
原文地址: https://blog.csdn.net/winter2121/article/details/78697805
本文转自网络文章，转载此文章仅为分享知识，如有侵权，请联系博主进行删除。