这道题收获还是蛮大的,首先思路上肯定是递归,因为上下状态都是关联的,然后给的2的100次方是没有用的,因为只问到2的62次方,
然后初始化的是每一个n的左右端点对应值,然后对于每一个区间都往上面进行拆分。
具体下标举个例子讨论一下就好了,调试的时候哪块不对可以加判断条件调,要是错了,就说明肯定是某个小下标打错了,在复制上面代码的时候一定要注意这一点。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int t;
//ll L,R;
ll dp[70][2],L[70],R[70];
void init(){
dp[1][0]=1;dp[1][1]=0;
L[1]=1;R[1]=1;
for(int i=2;i<=62;i++){
L[i]=1;R[i]=2*(R[i-1]-L[i-1]+1)+1;
dp[i][0]=dp[i-1][0]+1+dp[i-1][1];
dp[i][1]=dp[i-1][1]+dp[i-1][0];
}
}
ll dfs(ll l,ll r,int node){
if(l>r||node<1) return 0;
if(l==L[node]&&r==R[node]) return dp[node][0];
ll mid=(L[node]+R[node])/2;
// if(node==2) cout<<" mid = "<<mid<<endl;
if(r<=mid){
if(r==mid) return dfs(l,r-1,node-1)+1;
else{
// puts("nimabbi");
return dfs(l,r,node-1);
}
}
else{
if(l==mid) return 1+r-mid-dfs(R[node]-r+1,R[node]-mid,node-1);
else if(l>mid){
return r-l+1-dfs(R[node]-r+1,R[node]-l+1,node-1);
}
else{
// puts("niambi");
return dfs(l,mid-1,node-1)+1+r-mid-dfs(R[node]-r+1,R[node]-mid,node-1);
}
}
}
int main(){
// printf("%lld\n",(1ll<<61));
cin>>t;ll L,R;
init();
while(t--){
scanf("%lld%lld",&L,&R);
ll ans=dfs(L,R,62);
printf("%lld\n",ans);
}
}