输入数据包括多行,每行给出一组测试数据,包括两个整数m,n (1 <= m <= n <= 1000000000)。
对于每一组测试数据,输出一行,该行包含一个整数,给出结点m所在子树中包括的结点的数目。
3 12 0 0
4
import java.util.Scanner;
public class Main {
static int count=0;
static int n;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int m = scanner.nextInt();
n = scanner.nextInt();
fun(m);
System.out.println(count);
}
static void fun(int m){
if (m<=n){
count++;
fun(m*2);
fun(m*2+1);
}
}
}
while True:
try:
i,num = list(map(int,input().split()))
result,level = 1,1
leftNode,rightNode = 2*i,2*i+1
while rightNode <= num:
level *= 2
result += level
leftNode *= 2
rightNode = rightNode*2 + 1
if leftNode <= num:
result += num-leftNode+1
print(result)
except Exception:
break
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
int m = scanner.nextInt();
int n = scanner.nextInt();
System.out.println(findSubTree(m, n) - 1);
}
scanner.close();
}
static int findSubTree(int x, int n) {
if (x > n)
return 1;
return findSubTree(2 * x, n) + findSubTree(2 * x + 1, n);
}
}
/*
* 递归部分实际求的是树的虚拟叶结点数,所谓虚拟叶结点,是指把一棵树补成完全二叉树而
* 新添加的虚拟叶结点。 可以证明,虚拟叶结点数=树结点数+1。证明如下:
* 设虚拟叶结点数为x,有x = 2*n0 + n1, 设树总结点数为n,有n = n0 + n1 + n2。
* 树同时具有性质n0 = n2+1, 所以,x = n0
* + n1 + n2 + 1 = n+1。 注:上述ni是度为i的结点
*/
//很简单的分治法
#include <iostream>
using namespace std;
//一共有n个节点,m节点所在子树的节点个数
int Function(int m,int n){
if(m>n){
return 0;
}else{
return Function(2*m,n) + Function(2*m+1,n) +1;
}
}
int main()
{
int m,n;
while(scanf("%d%d",&m,&n)!=EOF){
if(m==0&&n==0){
break;
}
printf("%d\n",Function(m,n));
}
return 0;
}
#include<iostream>
using namespace std;
//const int maxn=100050;
//int tree[maxn];
int s;
int m,n;
void f(int temp){
if(temp<=n){
s++;
f(2*temp);
f(2*temp+1);
}
}
int main(){
while(cin>>m>>n){
s=0;
if(n==0&&m==0){
return 0;
}
f(m);
cout<<s<<endl;
}
return 0;
} #include<iostream>
#include<vector>
#include<queue>
using namespace std;
int subnum(int m, int n){ int num = 0; queue<int> q; q.push(m); while (!q.empty()){ int i = q.front(); q.pop(); if (i * 2 <= n){ num++; q.push(i*2); } if (i * 2 + 1 <= n){ num++; q.push(i * 2 + 1); } } return num;
}
int main(){ int m, n; while (cin >> m >> n){ cout<<subnum(m,n)<<endl; }
} #include<iostream>
#include<stdio.h>
#include<cstring>
#include<cmath>
using namespace std;
int f(int m,int n){
if(2*m>n) return 1;
if(2*m+1>n) return 2;
return 1+f(2*m,n)+f(2*m+1,n);
}
int main(){
int m,n;
while(cin>>m>>n){
cout<<f(m,n)<<endl;
}
return 0;
} #include<stdio.h>
#include<cmath>
int Line(int n){
return log(n)/log(2)+1;
}
int NodeNum(int l1,int l2,int m,int n){
if(l1==l2)
{
printf("==\n");
return 0;
}
int cnt=pow(2,l2-l1+1)-1;//计算2的几次方
int time=l2-l1;
int p1=m*pow(2,time);
int p2=m;
while(time--)
p2=p2*2+1;
if(p2<=n)
return cnt;
else if(p1<=n)
return cnt-(p2-n);
else
return pow(2,l2-l1)-1;
}
int main(){
int n,m;
while(scanf("%d%d",&m,&n)!=EOF){
int l1=Line(m);
int l2=Line(n);
int cnt=NodeNum(l1,l2,m,n);
printf("%d\n",cnt);
}
return 0;
} #include <stdio.h>
int m,n;
int main(){
int left,right,sum;
while(scanf("%d %d",&m,&n)!=EOF){
//根结点:所在子树为整个二叉树
if(m==1)
printf("%d\n",n);
//非根结点:从当前结点到此结点的子树最底层最右端的结点数目即为所求
else{
//sum-动态记录结点m所在子树中包括的结点的数目
//left.right-结点m所在子树某层最左端和最右端的结点编号
//初始化sum=1,即算入结点m
sum=1;
//求出结点m下一层两个结点的编号
left=2*m;
right=2*m+1;
//left.right有一者<=n时,循环
while(left<=n || right<=n){
//right<=n 说明当前层的所有结点均在完全二叉树内
if(right<=n)
sum+=(right-left+1);
//left<=n且right>n,说明当前层编号为n+1~right的结点不在完全二叉树内
//注意减去这部分
else if(left<=n && right>n)
sum+=(n-left+1);
left=2*left;
right=2*right+1;
}
//结果
printf("%d\n",sum);
}
}
return 0;
}
#include <iostream>
int main(){
int m,n;
while(std::cin>>m>>n)
{
if( m==0 && n==0) break;
int a=m,b=m,h=1;
while(a*2<=n)
{
h++;
a*=2;
b=b*2+1;
}
int s=(1<<h)-1 ;
if(n>b)
std::cout << s<<std::endl;
else
std::cout << s-(b-n)<<std::endl;
}
}
#include <iostream> #include <math.h> using namespace std; int getRlt(int n, int m) { int rlt; int k = int(log(n*1.0/m)/log(2.0)) + 1; int temp = n - m*pow(2, k-1) + 1; if(temp > pow(2, k-1)) { rlt = pow(2, k) - 1; } else { rlt = pow(2, k-1) -1 + temp; } return rlt; } int main() { int m, n; while(cin >> m >> n) { if(m==0 && n==0) break; cout << getRlt(n, m) << endl; } return 0; }
//用队列来统计孩子节点的个数
#include<stdio.h>
#include<queue>
using namespace std;
int main(){
int m,n;
while(scanf("%d %d",&m,&n)){
if(m==0&&n==0){
break;
}
int result=0;
queue<int> childrenTree;
childrenTree.push(m);
while(!childrenTree.empty()){
int current=childrenTree.front();
childrenTree.pop();
if(current*2<=n){
childrenTree.push(current*2);
result++;
}
if(current*2+1<=n){
childrenTree.push(current*2+1);
result++;
}
}
printf("%d\n",result+1);
}
return 0;
}