题:https://codeforces.com/contest/1245/problem/F
分析:转化为:求区间内满足a&b==0的对数(解释见代码)

///求满足a&b==0在区间【l,r】的对数
///推导:区间[2l,2r]可由[l,r]乘3倍得来
///原因:*2我们可以看成事左移1位,那么这个位置上,对于俩个数来说
/////////可以取0,1 或1,0或0,0才依然满足 a&b==0这个题目条件
/////////这个公式可以用递归推导回溯计算,
/////////当我们回递归到区间为奇数的情况的时候,我们想办法让它变成偶数
/////////假设[a,b]中a是奇数,那么我们就把它弄成a+1,然后加上漏算的部分即可
/////////g(x,y)表示在区间[0,b]中和x满足题目条件的个数
/////////然后漏算的部分就是 (g(a,b)-g(a,a))*2
/////////b为奇数的情况也照样这样分析
/////////完
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
ll g(int a,int b){
ll ans=0;
ll num=0;
for(int i=1;i<=b;i<<=1){
if(i&b){
b^=i;
if(!(a&b))
ans+=1ll<<num;
}
if(!(i&a)){///a在二进制下i位置为0的情况下,num就是计数这种情况的
num++;
}
}
return ans;
}
ll cal(int a,int b){
if(a==0)
return 2*b-1+cal(1,b);
if(a==b)
return 0;
ll ans=0;
if(a&1){///若左区间的值为奇数
ans+=(g(a,b)-g(a,a))*2;///乘2是对数可以互换,然后这个就是剪掉区间缩成偶数时加上漏加的部分,类似于用前缀和算区间和
a++;
}
if(b&1){///若右区间的值为偶数
ans+=(g(b-1,b)-g(b-1,a))*2;
b--;
}
return ans+3*cal(a/2,b/2);
}
int main(){
int t;
scanf("%d",&t);
while(t--){
int a,b;
scanf("%d%d",&a,&b);
printf("%I64d\n",cal(a,b+1));
}
return 0;
}
