递归地计算就可以。
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; long long len[70]; long long L,R; void init() { len[1]=1; for(int i=2; i<=60; i++) len[i]=2*len[i-1]+1; } long long f(long long p) { if(p<=0) return 0; if(p==1) return 1; int l=1,r=60; int ans; while(l<=r) { int mid=(l+r)/2; if(len[mid]<=p) ans=mid,l=mid+1; else r=mid-1; } long long res=0; res=res+(len[ans]+1)/2; long long g=p-(len[ans]+2)+1; if(len[ans]+1<=p) res++; if(len[ans]+2<=p) { long long pp=len[ans]-g; long long a=len[ans]-(len[ans]+1)/2; long long b=pp-f(pp); res=res+a-b; } return res; } int main() { init(); int T; scanf("%d",&T); while(T--) { scanf("%lld%lld",&L,&R); printf("%lld ",f(R)-f(L-1)); } return 0; }