一道进制转换,c++代码求解

题目描述
小s最近对数字情有独钟。他又发现了一种神奇的数字。对于数x,如果它二进制表示中只有一位是0,则x就会被小s所喜爱。比如5,二进制为101,则它被小s所喜爱。
现在,小s想知道,对于一个区间[L, R],有多少数是他所喜爱的。

输入格式
输入包含多组数据。
输入第一行T,表示数据组数。
每组数组仅有一行,包含两个正整数L, R。

输出格式
对于每组数据输出一行,表示答案。

输入样例
2
5 10
2015 2015
输出样例
2
1
数据范围与提示
【数据范围与约定】
30%: L, R <= 10^6, T <= 10
60%: L, R <= 10^10, T <= 100
100%: L, R <= 10^18, T <= 10000


#include<bits/stdc++.h>
using namespace std;
const int MAXN=210;
const int mod=998244353;
const int MOD=10010;
long long n,m,k,sum,cnt,a[MAXN],b[MAXN],dp[MAXN],t;
char str[MAXN],s[MAXN];
long long qpow(long long a,long long b){
    long long ans=1;
    while(b){
        if(b&1){
            ans=(ans*a);
        }
        a=(a*a);
        b/=2;
    }
    return ans;
} 
int main(){
    cin>>t;
    a[0]=1;
    for(int i=1;i<=200;i++){
        a[i]=a[i-1]+i-1;
    }
    while(t--){
        cin>>n>>m;
        sum=0;
        for(long long i=0;i<=200;i++)
            if(m<qpow(2,i)){
                k=i;
                break;
            }
        long long x=qpow(2,k)-1;
        for(long long i=k-2;i>=0;i--){
            if(m>=(x-qpow(2,i))){
                sum++;
            }
        }
        for(long long i=1;i<=200;i++){
            if(n<qpow(2,i)){
                cnt=i;
                break;
            }
        }   
        long long y=qpow(2,cnt)-1;
        for(long long i=0;i<cnt-1;i++){
            if(n<=(y-qpow(2,i))){
                sum++;
            }
        }
        sum+=a[k-1]-a[cnt];
        cout<<sum<<endl;
    }
    return 0;
}

进制转换这是最基本的啊,十进制转2进制的话,不停除以二取余,看看余数有多少个1就行。
不过这样很可能超时,推荐用位运算,右移一位相当于除以2,然后求除以二的余数,就和1进行按位与。