1 #include<bits/stdc++.h>
2 using namespace std;
3 const int maxn=50000;
4 int a,b,n,m,tmp,s[maxn+5],t[(maxn+5)<<2];
5 void build(int l,int r,int x){
6 int mid=(l+r)>>1;
7 if(l==r){t[x]=s[mid];return;}
8 build(l,mid,x<<1);
9 build(mid+1,r,x<<1|1);
10 t[x]=max(t[x<<1],t[x<<1|1]);
11 }
12 int query(int l,int r,int x){
13 if(a<=l&&b>=r)return t[x];//如果该节点表示的区间恰好是要查询的区间,直接返回结果,即[l,r]是[a,b]的一个子集,直接返回最大值,不用继续往下查找
14 else{
15 int mid=(l+r)>>1;
16 if(b<=mid)return query(l,mid,x<<1);//判断(编号)区间在哪棵子树上[a,b]在[l,r]的左子树[l,mid]上
17 else if(a>mid)return query(mid+1,r,x<<1|1);//[a,b]在[l,r]的右子树[mid+1,r]上
18 else return max(query(l,mid,x<<1),query(mid+1,r,x<<1|1));//表示[a,b],有一部分在[l,mid]上,有一部分在[mid+1,r]上,直接返回左右区间的最大值
19 }
20 }
21 int main(){
22 for(int i=1;i<=maxn;++i){//预处理打表
23 tmp=i;n=1;
24 while(tmp!=1){tmp=(tmp%2)?3*tmp+1:tmp/2;++n;}
25 s[i]=n;
26 }
27 build(1,maxn,1);//建树
28 while(~scanf("%d",&m)){
29 while(m--){
30 scanf("%d %d",&a,&b);
31 printf("%d
",query(1,maxn,1));
32 }
33 }
34 return 0;
35 }